├── plugin ├── .npmignore ├── references.d.ts ├── tsconfig.json ├── package.json ├── index.css ├── index.d.ts ├── README.md ├── index.ts └── index.js ├── demo.gif ├── demo ├── app │ ├── img │ │ ├── alert.jpg │ │ └── marcel.jpg │ ├── app.ts │ ├── App_Resources │ │ ├── iOS │ │ │ ├── icon.png │ │ │ ├── Default.png │ │ │ ├── icon-40.png │ │ │ ├── icon-60.png │ │ │ ├── icon-72.png │ │ │ ├── icon-76.png │ │ │ ├── icon@2x.png │ │ │ ├── Default@2x.png │ │ │ ├── Icon-Small.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-72@2x.png │ │ │ ├── icon-76@2x.png │ │ │ ├── Icon-Small-50.png │ │ │ ├── Icon-Small@2x.png │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-667h@2x.png │ │ │ ├── Default-736h@3x.png │ │ │ ├── Default-Landscape.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Icon-Small-50@2x.png │ │ │ ├── Default-Portrait@2x.png │ │ │ ├── Default-Landscape@2x.png │ │ │ ├── Default-Landscape@3x.png │ │ │ ├── Default-Landscape-568h@2x.png │ │ │ ├── Default-Landscape-667h@2x.png │ │ │ ├── build.xcconfig │ │ │ └── Info.plist │ │ └── Android │ │ │ ├── drawable-hdpi │ │ │ └── icon.png │ │ │ ├── drawable-ldpi │ │ │ └── icon.png │ │ │ ├── drawable-mdpi │ │ │ └── icon.png │ │ │ ├── drawable-nodpi │ │ │ └── splashscreen.9.png │ │ │ ├── app.gradle │ │ │ └── AndroidManifest.xml │ ├── app.js │ ├── references.d.ts │ ├── main-view-model.ts │ ├── main-page.xml │ ├── main-view-model.js │ ├── package.json │ ├── app.css │ ├── main-page.js │ └── main-page.ts ├── hooks │ ├── before-watch │ │ └── nativescript-dev-typescript.js │ └── before-prepare │ │ └── nativescript-dev-typescript.js ├── references.d.ts ├── livesync.cmd ├── tsconfig.json └── package.json ├── .gitignore ├── LICENSE └── README.md /plugin/.npmignore: -------------------------------------------------------------------------------- 1 | *.map 2 | index.ts 3 | tsconfig.json 4 | references.d.ts -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo.gif -------------------------------------------------------------------------------- /demo/app/img/alert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/img/alert.jpg -------------------------------------------------------------------------------- /demo/app/img/marcel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/img/marcel.jpg -------------------------------------------------------------------------------- /demo/app/app.ts: -------------------------------------------------------------------------------- 1 | import Application = require("application"); 2 | 3 | Application.start({ moduleName: "main-page" }); 4 | -------------------------------------------------------------------------------- /demo/hooks/before-watch/nativescript-dev-typescript.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nativescript-dev-typescript/lib/watch.js"); 2 | -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /pushall.sh 2 | /demo/node_modules 3 | /demo/platforms 4 | /plugin/chat-view-common.js.map 5 | /demo/app/*.map 6 | /plugin/*.map 7 | -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-40.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-60.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-72.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-76.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon@2x.png -------------------------------------------------------------------------------- /demo/hooks/before-prepare/nativescript-dev-typescript.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nativescript-dev-typescript/lib/before-prepare.js"); 2 | -------------------------------------------------------------------------------- /demo/references.d.ts: -------------------------------------------------------------------------------- 1 | /// Needed for autocompletion and compilation. -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Icon-Small.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-40@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-60@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-72@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/icon-76@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Icon-Small-50.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Icon-Small@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-568h@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-667h@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-736h@3x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Landscape.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Portrait.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Portrait@2x.png -------------------------------------------------------------------------------- /demo/app/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var Application = require("application"); 3 | Application.start({ moduleName: "main-page" }); 4 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/Android/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/Android/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/Android/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Landscape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Landscape@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Landscape@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Landscape@3x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Landscape-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Landscape-568h@2x.png -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Default-Landscape-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/iOS/Default-Landscape-667h@2x.png -------------------------------------------------------------------------------- /demo/app/references.d.ts: -------------------------------------------------------------------------------- 1 | /// Enable smart suggestions and completions in Visual Studio Code JavaScript projects. 2 | -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/nativescript-chatview/HEAD/demo/app/App_Resources/Android/drawable-nodpi/splashscreen.9.png -------------------------------------------------------------------------------- /plugin/references.d.ts: -------------------------------------------------------------------------------- 1 | /// Enable smart suggestions and completions in Visual Studio Code JavaScript projects. 2 | -------------------------------------------------------------------------------- /demo/app/main-view-model.ts: -------------------------------------------------------------------------------- 1 | import {Observable} from "data/observable"; 2 | 3 | export function createViewModel() { 4 | var viewModel = new Observable(); 5 | 6 | return viewModel; 7 | } 8 | -------------------------------------------------------------------------------- /demo/app/main-page.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /demo/app/main-view-model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var observable_1 = require("data/observable"); 3 | function createViewModel() { 4 | var viewModel = new observable_1.Observable(); 5 | return viewModel; 6 | } 7 | exports.createViewModel = createViewModel; 8 | //# sourceMappingURL=main-view-model.js.map -------------------------------------------------------------------------------- /demo/livesync.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | CLS 3 | 4 | CALL tns plugin remove nativescript-chatview 5 | 6 | CD .. 7 | CD plugin 8 | ECHO Rebuild plugin... 9 | CALL tsc 10 | ECHO Done 11 | 12 | CD .. 13 | CD demo 14 | 15 | CALL tns plugin add ..\plugin 16 | 17 | CALL tns livesync --watch 18 | -------------------------------------------------------------------------------- /plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "noEmitHelpers": true, 9 | "noEmitOnError": true 10 | } 11 | } -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/build.xcconfig: -------------------------------------------------------------------------------- 1 | // You can add custom settings here 2 | // for example you can uncomment the following line to force distribution code signing 3 | // CODE_SIGN_IDENTITY = iPhone Distribution 4 | // ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 5 | // ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Brand Assets; 6 | -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "noEmitHelpers": true, 9 | "noEmitOnError": true 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | "platforms" 14 | ] 15 | } -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/app.gradle: -------------------------------------------------------------------------------- 1 | // Add your native dependencies here: 2 | 3 | // Uncomment to add recyclerview-v7 dependency 4 | //dependencies { 5 | // compile 'com.android.support:recyclerview-v7:+' 6 | //} 7 | 8 | android { 9 | defaultConfig { 10 | generatedDensities = [] 11 | } 12 | aaptOptions { 13 | additionalParameters "--no-version-vectors" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /demo/app/package.json: -------------------------------------------------------------------------------- 1 | {"name":"tns-template-hello-world","main":"app.js","version":"2.0.0","author":{"name":"Telerik","email":"support@telerik.com"},"description":"Nativescript hello-world project template","license":"Apache-2.0","keywords":["telerik","mobile","nativescript","{N}","tns","appbuilder","template"],"repository":{"type":"git","url":"git://github.com/NativeScript/template-hello-world.git"},"bugs":{"url":"https://github.com/NativeScript/template-hello-world/issues"},"homepage":"https://github.com/NativeScript/template-hello-world","android":{"v8Flags":"--expose_gc"},"readme":"ERROR: No README data found!","_id":"tns-template-hello-world@2.0.0","_from":"tns-template-hello-world@2.0.0"} -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "NativeScript Application", 3 | "license": "SEE LICENSE IN ", 4 | "readme": "NativeScript Application", 5 | "repository": "", 6 | "nativescript": { 7 | "id": "org.nativescript.NativeScriptChatViewDemo", 8 | "tns-android": { 9 | "version": "2.4.1" 10 | } 11 | }, 12 | "dependencies": { 13 | "nativescript-chatview": "file:..\\plugin", 14 | "tns-core-modules": "^2.4.1" 15 | }, 16 | "devDependencies": { 17 | "babel-traverse": "6.19.0", 18 | "babel-types": "6.19.0", 19 | "babylon": "6.14.1", 20 | "lazy": "1.0.11", 21 | "nativescript-dev-typescript": "^0.3.2", 22 | "typescript": "^1.8.10" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nativescript-chatview", 3 | "description": "NativeScript UI module for implementing WhatsApp like chat applications.", 4 | "version": "1.0.3", 5 | "nativescript": { 6 | "platforms": { 7 | "android": "1.1.0", 8 | "ios": "1.0.0" 9 | } 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/mkloubert/nativescript-chatview" 14 | }, 15 | "keywords": [ 16 | "NativeScript", 17 | "API", 18 | "HTTP", 19 | "REST", 20 | "JSON", 21 | "XML" 22 | ], 23 | "author": { 24 | "name": "Marcel Joachim Kloubert", 25 | "email": "marcel.kloubert@gmx.net" 26 | }, 27 | "license": { 28 | "type": "MIT", 29 | "url": "https://github.com/mkloubert/nativescript-chatview/blob/master/LICENSE" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/mkloubert/nativescript-chatview/issues" 33 | }, 34 | "homepage": "https://github.com/mkloubert/nativescript-chatview", 35 | "readmeFilename": "README.md", 36 | "dependencies": {} 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Marcel Kloubert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/app/App_Resources/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /demo/app/App_Resources/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | icon.png 13 | CFBundleIcons 14 | 15 | CFBundlePrimaryIcon 16 | 17 | CFBundleIconFiles 18 | 19 | icon-40 20 | icon-60 21 | icon-72 22 | icon-76 23 | Icon-Small 24 | Icon-Small-50 25 | 26 | UIPrerenderedIcon 27 | 28 | 29 | 30 | CFBundleInfoDictionaryVersion 31 | 6.0 32 | CFBundleName 33 | ${PRODUCT_NAME} 34 | CFBundlePackageType 35 | APPL 36 | CFBundleShortVersionString 37 | 1.0 38 | CFBundleSignature 39 | ???? 40 | CFBundleVersion 41 | 1.0 42 | LSRequiresIPhoneOS 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIRequiresFullScreen 47 | 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /demo/app/app.css: -------------------------------------------------------------------------------- 1 | 2 | .nsChatView-view .nsChatView-sendMessageArea { 3 | margin: 4,0,0,0; 4 | background-color: #e8e8e8; 5 | } 6 | 7 | .nsChatView-view .nsChatView-sendMessageArea Button { 8 | background-color: transparent; 9 | margin: 0; 10 | } 11 | 12 | .nsChatView-view .nsChatView-messageList { 13 | background-color: transparent; 14 | border-color: transparent; 15 | border-width: 0; 16 | margin: 0; 17 | } 18 | 19 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-avatar, 20 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-avatar { 21 | margin: 8; 22 | border-radius: 32; 23 | width: 64; 24 | } 25 | 26 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-separator, 27 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-separator { 28 | border-color: transparent; 29 | border-width: 0; 30 | width: 32; 31 | } 32 | 33 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-message, 34 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-message { 35 | margin: 8; 36 | } 37 | 38 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea, 39 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 40 | border-radius: 8; 41 | } 42 | 43 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea { 44 | background-color: #edeef2; 45 | } 46 | 47 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 48 | background-color: #00b863; 49 | } 50 | 51 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content, 52 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content { 53 | margin: 12,16,12,16; 54 | } 55 | 56 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea Label, 57 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea Label { 58 | margin: 0; 59 | } 60 | 61 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content Label { 62 | color: black; 63 | } 64 | 65 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content Label { 66 | color: white; 67 | } 68 | 69 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content .nsChatView-date, 70 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content .nsChatView-date { 71 | font-size: 11; 72 | margin-bottom: 12; 73 | } 74 | 75 | .nsChatView-view .nsChatView-messageField { 76 | font-size: 14; 77 | } 78 | -------------------------------------------------------------------------------- /plugin/index.css: -------------------------------------------------------------------------------- 1 | 2 | .nsChatView-view .nsChatView-sendMessageArea { 3 | margin: 4,0,0,0; 4 | background-color: #e8e8e8; 5 | } 6 | 7 | .nsChatView-view .nsChatView-sendMessageArea Button { 8 | background-color: transparent; 9 | margin: 0; 10 | } 11 | 12 | .nsChatView-view .nsChatView-messageList { 13 | background-color: transparent; 14 | border-color: transparent; 15 | border-width: 0; 16 | margin: 0; 17 | } 18 | 19 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-avatar, 20 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-avatar { 21 | margin: 8; 22 | border-radius: 32; 23 | width: 64; 24 | } 25 | 26 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-separator, 27 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-separator { 28 | border-color: transparent; 29 | border-width: 0; 30 | width: 32; 31 | } 32 | 33 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-message, 34 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-message { 35 | margin: 8; 36 | } 37 | 38 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea, 39 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 40 | border-radius: 8; 41 | } 42 | 43 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea { 44 | background-color: #edeef2; 45 | } 46 | 47 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 48 | background-color: #00b863; 49 | } 50 | 51 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content, 52 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content { 53 | margin: 12,16,12,16; 54 | } 55 | 56 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea Label, 57 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea Label { 58 | margin: 0; 59 | } 60 | 61 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content Label { 62 | color: black; 63 | } 64 | 65 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content Label { 66 | color: white; 67 | } 68 | 69 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content .nsChatView-date, 70 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content .nsChatView-date { 71 | font-size: 11; 72 | margin-bottom: 12; 73 | } 74 | 75 | .nsChatView-view .nsChatView-messageField { 76 | font-size: 14; 77 | } 78 | -------------------------------------------------------------------------------- /plugin/index.d.ts: -------------------------------------------------------------------------------- 1 | import Button = require("ui/button"); 2 | import ListView = require("ui/list-view"); 3 | import GridLayout = require("ui/layouts/grid-layout"); 4 | import Observable = require("data/observable"); 5 | import ObservableArray = require("data/observable-array"); 6 | import TextField = require("ui/text-field"); 7 | /** 8 | * A view for displaying chat messages. 9 | */ 10 | export declare class ChatView extends GridLayout.GridLayout { 11 | /** 12 | * The name of the event that is raised when the "SEND" button is clicked. 13 | */ 14 | static sendChatMessageButtonTapEvent: string; 15 | private _messageField; 16 | private _messageList; 17 | private _messages; 18 | private _sendMessageArea; 19 | private _sendMessageButton; 20 | private _sendChatMessageButtonTapEventListeners; 21 | /** @inheritdoc */ 22 | constructor(json?: any); 23 | /** 24 | * Appends a list of messages. 25 | * 26 | * @param {IChatMessage} ...msgs One or more messages to append. 27 | */ 28 | appendMessages(...msgs: IChatMessage[]): void; 29 | /** 30 | * Focus the text field with the chat message to send. 31 | * 32 | * @return {Boolean} Operation was successful or not. 33 | */ 34 | focusMessageField(): boolean; 35 | /** 36 | * Inserts chat messages at a specific position. 37 | * 38 | * @param {Number} index The zero based index where the messages should be inserted. 39 | * @param {IChatMessage} ...msgs One or more messages to insert. 40 | */ 41 | insertMessages(index: number, ...msgs: IChatMessage[]): void; 42 | /** 43 | * Gets the input field that stores the chat message that should be send. 44 | */ 45 | messageField: TextField.TextField; 46 | /** 47 | * Gets the list that displays the chat messages. 48 | */ 49 | messageList: ListView.ListView; 50 | /** 51 | * Gets the array of messages. 52 | */ 53 | messages: ObservableArray.ObservableArray; 54 | /** 55 | * Adds an event handler that is invoked when the "SEND" button is clicked. 56 | * 57 | * @param {Function} handler The handler to add. 58 | */ 59 | notifyOnSendMessageTap(handler: (eventData: SendMessageTappedEventData) => void): void; 60 | /** 61 | * Prepends a list of messages. 62 | * 63 | * @param {IChatMessage} ...msgs One or more messages to prepend. 64 | */ 65 | prependMessages(...msgs: IChatMessage[]): void; 66 | /** 67 | * Resets the value of the chat message field. 68 | */ 69 | resetMessage(): void; 70 | /** 71 | * Gets the control that contains the chat message field 72 | * and the "SEND" button. 73 | */ 74 | sendMessageArea: GridLayout.GridLayout; 75 | /** 76 | * Gets the button that is used to send a chat message. 77 | */ 78 | sendMessageButton: Button.Button; 79 | /** 80 | * Gets and sets the caption of the "SEND" button. 81 | */ 82 | sendMessageButtonCaption: string; 83 | /** 84 | * Gets and sets the hint text for the chat message field. 85 | */ 86 | typeMessageHint: string; 87 | } 88 | /** 89 | * Describes an object that stores required data for a char message. 90 | */ 91 | export interface IChatMessage { 92 | /** 93 | * The date. 94 | * 95 | * @property 96 | */ 97 | date?: any; 98 | /** 99 | * The image source. 100 | * 101 | * @property 102 | */ 103 | image?: any; 104 | /** 105 | * Defines if the displayed item is aligned on the right side or not. 106 | * 107 | * @property 108 | */ 109 | isRight?: boolean; 110 | /** 111 | * The message value. 112 | * 113 | * @property 114 | */ 115 | message?: any; 116 | } 117 | /** 118 | * Data for an event that is raised when the "SEND" button is clicked. 119 | */ 120 | export declare class SendMessageTappedEventData implements Observable.EventData { 121 | private _message; 122 | private _object; 123 | /** 124 | * Initializes a new instance of that class. 125 | * 126 | * @param {ChatView} view The underlying view. 127 | * @param {String} msg 128 | */ 129 | constructor(view: ChatView, msg: string); 130 | /** @inheritdoc */ 131 | eventName: string; 132 | /** 133 | * Focuses the chat message field. 134 | * 135 | * @return {Boolean} Operation was successful or not. 136 | */ 137 | focusTextField(): boolean; 138 | /** 139 | * Gets the message to send. 140 | */ 141 | message: string; 142 | /** @inheritdoc */ 143 | object: ChatView; 144 | /** 145 | * Resets the message value. 146 | */ 147 | resetMessage(): void; 148 | /** 149 | * Scrolls to bottom. 150 | */ 151 | scrollToBottom(): void; 152 | } 153 | -------------------------------------------------------------------------------- /demo/app/main-page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var ChatViewModule = require("nativescript-chatview"); 3 | var Timer = require("timer"); 4 | var TypeUtils = require("utils/types"); 5 | var ViewModel = require("./main-view-model"); 6 | function createAnswer(msg) { 7 | if (/(\s*)([0-9]+)(\.?)([0-9]*)(\s*)([\+|\-|\*|\/])(\s*)([0-9]+)(\.?)([0-9]*)/i.test(msg)) { 8 | var result; 9 | eval("result = " + msg + ";"); 10 | return result; 11 | } 12 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "how", "are", "you")) { 13 | return "Fine!"; 14 | } 15 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "what", "time", "is", "it")) { 16 | return getTime(); 17 | } 18 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "hi")) { 19 | return "Hi! How are you?"; 20 | } 21 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "fine")) { 22 | return "Cool!"; 23 | } 24 | return 'You said: "' + msg + '"'; 25 | } 26 | function getSimilarity(left, right) { 27 | if (left === right) { 28 | return 1; 29 | } 30 | if (TypeUtils.isNullOrUndefined(left) || 31 | TypeUtils.isNullOrUndefined(right)) { 32 | return 0; 33 | } 34 | left = left.toLowerCase().trim(); 35 | right = right.toLowerCase().trim(); 36 | var distance = 0; 37 | if (left !== right) { 38 | var matrix = new Array(left.length + 1); 39 | for (var i = 0; i < matrix.length; i++) { 40 | matrix[i] = new Array(right.length + 1); 41 | for (var ii = 0; ii < matrix[i].length; ii++) { 42 | matrix[i][ii] = 0; 43 | } 44 | } 45 | for (var i = 0; i <= left.length; i++) { 46 | matrix[i][0] = i; 47 | } 48 | for (var j = 0; j <= right.length; j++) { 49 | matrix[0][j] = j; 50 | } 51 | for (var i = 0; i < left.length; i++) { 52 | for (var j = 0; j < right.length; j++) { 53 | if (left[i] === right[j]) { 54 | matrix[i + 1][j + 1] = matrix[i][j]; 55 | } 56 | else { 57 | matrix[i + 1][j + 1] = Math.min(matrix[i][j + 1] + 1, matrix[i + 1][j] + 1); 58 | matrix[i + 1][j + 1] = Math.min(matrix[i + 1][j + 1], matrix[i][j] + 1); 59 | } 60 | } 61 | distance = matrix[left.length][right.length]; 62 | } 63 | } 64 | return 1.0 - distance / Math.max(left.length, right.length); 65 | } 66 | function checkForAllTerms(str) { 67 | var terms = []; 68 | for (var _i = 1; _i < arguments.length; _i++) { 69 | terms[_i - 1] = arguments[_i]; 70 | } 71 | var parts = str.split(" "); 72 | for (var i = 0; i < parts.length; i++) { 73 | var p = parts[i]; 74 | if (p.trim() === "") { 75 | continue; 76 | } 77 | var found = false; 78 | for (var ii = 0; ii < terms.length; ii++) { 79 | var t = terms[ii]; 80 | if (getSimilarity(p, t) >= 0.5) { 81 | found = true; 82 | break; 83 | } 84 | } 85 | if (!found) { 86 | return false; 87 | } 88 | } 89 | return true; 90 | } 91 | function getLettersAndDigitsOnly(str) { 92 | var result = ""; 93 | for (var i = 0; i < str.length; i++) { 94 | if (/[a-zA-Z0-9]/i.test(str[i])) { 95 | result += str[i]; 96 | } 97 | else if (/[\s]/i.test(str[i])) { 98 | result += " "; 99 | } 100 | } 101 | return result; 102 | } 103 | function getTime() { 104 | var now = new Date(); 105 | var hours = now.getHours(); 106 | return numberToString(hours == 12 ? 12 : (hours % 12)) + ":" + numberToString(now.getMinutes()) + " " + 107 | (hours < 13 ? "AM" : "PM"); 108 | } 109 | function numberToString(n) { 110 | var str = "" + n; 111 | if (n < 10) { 112 | str = "0" + str; 113 | } 114 | return str; 115 | } 116 | function onNavigatingTo(args) { 117 | var page = args.object; 118 | page.bindingContext = ViewModel.createViewModel(); 119 | var chatView = new ChatViewModule.ChatView(); 120 | chatView.sendMessageButtonCaption = "Send"; 121 | chatView.typeMessageHint = "Your message for Albert"; 122 | chatView.notifyOnSendMessageTap(function (eventData) { 123 | eventData.object.appendMessages({ 124 | date: getTime(), 125 | isRight: true, 126 | image: "~/img/marcel.jpg", 127 | message: eventData.message, 128 | }); 129 | eventData.resetMessage(); 130 | eventData.scrollToBottom(); 131 | eventData.focusTextField(); 132 | Timer.setTimeout(function () { 133 | eventData.object.appendMessages({ 134 | date: getTime(), 135 | isRight: false, 136 | image: "~/img/alert.jpg", 137 | message: createAnswer(eventData.message), 138 | }); 139 | }, Math.floor(Math.random() * 2000)); 140 | }); 141 | chatView.focusMessageField(); 142 | page.content = chatView; 143 | } 144 | exports.onNavigatingTo = onNavigatingTo; 145 | //# sourceMappingURL=main-page.js.map -------------------------------------------------------------------------------- /demo/app/main-page.ts: -------------------------------------------------------------------------------- 1 | import ChatViewModule = require("nativescript-chatview"); 2 | import Frame = require("ui/frame"); 3 | import PageModule = require("ui/page"); 4 | import Timer = require("timer"); 5 | import TypeUtils = require("utils/types"); 6 | import View = require("ui/core/view"); 7 | import ViewModel = require("./main-view-model"); 8 | 9 | function createAnswer(msg) : string { 10 | if (/(\s*)([0-9]+)(\.?)([0-9]*)(\s*)([\+|\-|\*|\/])(\s*)([0-9]+)(\.?)([0-9]*)/i.test(msg)) { 11 | var result; 12 | eval("result = " + msg + ";"); 13 | 14 | return result; 15 | } 16 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "how", "are", "you")) { 17 | return "Fine!"; 18 | } 19 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "what", "time", "is", "it")) { 20 | return getTime(); 21 | } 22 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "hi")) { 23 | return "Hi! How are you?"; 24 | } 25 | else if (checkForAllTerms(getLettersAndDigitsOnly(msg), "fine")) { 26 | return "Cool!"; 27 | } 28 | 29 | return 'You said: "' + msg + '"'; 30 | } 31 | 32 | function getSimilarity(left: string, right: string) : number { 33 | if (left === right) { 34 | return 1; 35 | } 36 | 37 | if (TypeUtils.isNullOrUndefined(left) || 38 | TypeUtils.isNullOrUndefined(right)) { 39 | return 0; 40 | } 41 | 42 | left = left.toLowerCase().trim(); 43 | right = right.toLowerCase().trim(); 44 | 45 | var distance = 0; 46 | 47 | if (left !== right) { 48 | var matrix = new Array(left.length + 1); 49 | for (var i = 0; i < matrix.length; i++) { 50 | matrix[i] = new Array(right.length + 1); 51 | 52 | for (var ii = 0; ii < matrix[i].length; ii++) { 53 | matrix[i][ii] = 0; 54 | } 55 | } 56 | 57 | for (var i = 0; i <= left.length; i++) { 58 | matrix[i][0] = i; 59 | } 60 | 61 | for (var j = 0; j <= right.length; j++) { 62 | matrix[0][j] = j; 63 | } 64 | 65 | for (var i = 0; i < left.length; i++) { 66 | for (var j = 0; j < right.length; j++) { 67 | if (left[i] === right[j]) { 68 | matrix[i + 1][j + 1] = matrix[i][j]; 69 | } 70 | else { 71 | matrix[i + 1][j + 1] = Math.min(matrix[i][j + 1] + 1, 72 | matrix[i + 1][j] + 1); 73 | 74 | matrix[i + 1][j + 1] = Math.min(matrix[i + 1][j + 1], 75 | matrix[i][j] + 1); 76 | } 77 | } 78 | 79 | distance = matrix[left.length][right.length]; 80 | } 81 | } 82 | 83 | return 1.0 - distance / Math.max(left.length, 84 | right.length); 85 | } 86 | 87 | function checkForAllTerms(str: string, ...terms: string[]) : boolean { 88 | var parts = str.split(" "); 89 | for (var i = 0; i < parts.length; i++) { 90 | var p = parts[i]; 91 | if (p.trim() === "") { 92 | continue; 93 | } 94 | 95 | var found = false; 96 | 97 | for (var ii = 0; ii < terms.length; ii++) { 98 | var t = terms[ii]; 99 | 100 | if (getSimilarity(p, t) >= 0.5) { 101 | found = true; 102 | break; 103 | } 104 | } 105 | 106 | if (!found) { 107 | return false; 108 | } 109 | } 110 | 111 | return true; 112 | } 113 | 114 | function getLettersAndDigitsOnly(str: string) : string { 115 | var result = ""; 116 | 117 | for (var i = 0; i < str.length; i++) { 118 | if (/[a-zA-Z0-9]/i.test(str[i])) { 119 | result += str[i]; 120 | } 121 | else if (/[\s]/i.test(str[i])) { 122 | result += " "; 123 | } 124 | } 125 | 126 | return result; 127 | } 128 | 129 | function getTime() : string { 130 | var now = new Date(); 131 | 132 | var hours = now.getHours(); 133 | return numberToString(hours == 12 ? 12 : (hours % 12)) + ":" + numberToString(now.getMinutes()) + " " + 134 | (hours < 13 ? "AM" : "PM"); 135 | } 136 | 137 | function numberToString(n: number): string { 138 | var str = "" + n; 139 | if (n < 10) { 140 | str = "0" + str; 141 | } 142 | 143 | return str; 144 | } 145 | 146 | export function onNavigatingTo(args) { 147 | var page = args.object; 148 | page.bindingContext = ViewModel.createViewModel(); 149 | 150 | var chatView = new ChatViewModule.ChatView(); 151 | chatView.sendMessageButtonCaption = "Send"; 152 | chatView.typeMessageHint = "Your message for Albert"; 153 | 154 | chatView.notifyOnSendMessageTap((eventData) => { 155 | eventData.object.appendMessages({ 156 | date: getTime(), 157 | isRight: true, 158 | image: "~/img/marcel.jpg", 159 | message: eventData.message, 160 | }); 161 | 162 | eventData.resetMessage(); 163 | eventData.scrollToBottom(); 164 | eventData.focusTextField(); 165 | 166 | Timer.setTimeout(() => { 167 | eventData.object.appendMessages({ 168 | date: getTime(), 169 | isRight: false, 170 | image: "~/img/alert.jpg", 171 | message: createAnswer(eventData.message), 172 | }); 173 | }, Math.floor(Math.random() * 2000)); 174 | }); 175 | 176 | chatView.focusMessageField(); 177 | 178 | page.content = chatView; 179 | } 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm](https://img.shields.io/npm/v/nativescript-chatview.svg)](https://www.npmjs.com/package/nativescript-chatview) 2 | [![npm](https://img.shields.io/npm/dt/nativescript-chatview.svg?label=npm%20downloads)](https://www.npmjs.com/package/nativescript-chatview) 3 | 4 | # NativeScript ChatView 5 | 6 | A [NativeScript](https://nativescript.org/) UI module for implementing WhatsApp like chat applications. 7 | 8 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SSS259WRLTWU2) 9 | 10 | ## License 11 | 12 | [MIT license](https://raw.githubusercontent.com/mkloubert/nativescript-chatview/master/LICENSE) 13 | 14 | ## Platforms 15 | 16 | * Android 17 | * iOS 18 | 19 | ## Installation 20 | 21 | Run 22 | 23 | ```bash 24 | tns plugin add nativescript-chatview 25 | ``` 26 | 27 | inside your app project to install the module. 28 | 29 | ## Demo 30 | 31 | The demo app can be found [here](https://github.com/mkloubert/nativescript-chatview/tree/master/demo). 32 | 33 | ![Demo app](https://raw.githubusercontent.com/mkloubert/nativescript-chatview/master/demo.gif) 34 | 35 | ## Usage 36 | 37 | ### Include 38 | 39 | ```javascript 40 | import ChatView = require("nativescript-chatview"); 41 | ``` 42 | 43 | ### Create view 44 | 45 | ```xml 46 | 48 | 49 | ``` 50 | 51 | ```typescript 52 | import ChatView = require("nativescript-chatview"); 53 | 54 | function getTime() : string { 55 | var now = new Date(); 56 | 57 | var hours = now.getHours(); 58 | return numberToString(hours == 12 ? 12 : (hours % 12)) + ":" + numberToString(now.getMinutes()) + " " + 59 | (hours < 13 ? "AM" : "PM"); 60 | } 61 | 62 | export function onNavigatingTo(args) { 63 | var page = args.object; 64 | 65 | // create view 66 | var chatView = new ChatView.ChatView(); 67 | 68 | // register event when user taps 69 | // on SEND button 70 | chatView.notifyOnSendMessageTap((eventData: ChatView.SendMessageTappedEventData) => { 71 | // add a chat message 72 | eventData.object.appendMessages({ 73 | date: getTime(), 74 | isRight: true, 75 | image: "~/img/avatar.jpg", 76 | message: eventData.message, 77 | }); 78 | }); 79 | 80 | // focus text field 81 | chatView.focusMessageField(); 82 | 83 | page.content = chatView; 84 | } 85 | ``` 86 | 87 | #### The XML way 88 | 89 | ```xml 90 | 93 | 94 | 95 | 96 | ``` 97 | 98 | ### Styling 99 | 100 | Add the following CSS to your code: 101 | 102 | ```css 103 | .nsChatView-view .nsChatView-sendMessageArea { 104 | margin: 4,0,0,0; 105 | background-color: #e8e8e8; 106 | } 107 | 108 | .nsChatView-view .nsChatView-sendMessageArea Button { 109 | background-color: transparent; 110 | margin: 0; 111 | } 112 | 113 | .nsChatView-view .nsChatView-messageList { 114 | background-color: transparent; 115 | border-color: transparent; 116 | border-width: 0; 117 | margin: 0; 118 | } 119 | 120 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-avatar, 121 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-avatar { 122 | margin: 8; 123 | border-radius: 32; 124 | width: 64; 125 | } 126 | 127 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-separator, 128 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-separator { 129 | border-color: transparent; 130 | border-width: 0; 131 | width: 32; 132 | } 133 | 134 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-message, 135 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-message { 136 | margin: 8; 137 | } 138 | 139 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea, 140 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 141 | border-radius: 8; 142 | } 143 | 144 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea { 145 | background-color: #edeef2; 146 | } 147 | 148 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea { 149 | background-color: #00b863; 150 | } 151 | 152 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content, 153 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content { 154 | margin: 12,16,12,16; 155 | } 156 | 157 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea Label, 158 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea Label { 159 | margin: 0; 160 | } 161 | 162 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content Label { 163 | color: black; 164 | } 165 | 166 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content Label { 167 | color: white; 168 | } 169 | 170 | .nsChatView-view .nsChatView-messageList .nsChatView-item-left .nsChatView-messageArea .nsChatView-content .nsChatView-date, 171 | .nsChatView-view .nsChatView-messageList .nsChatView-item-right .nsChatView-messageArea .nsChatView-content .nsChatView-date { 172 | font-size: 11; 173 | margin-bottom: 12; 174 | } 175 | 176 | .nsChatView-view .nsChatView-messageField { 177 | font-size: 14; 178 | } 179 | ``` 180 | 181 | To understand how a `ChatView` is defined, you can have a look at the following XML definition: 182 | 183 | ```xml 184 | 186 | 187 | 188 | 193 | 194 | 195 | 196 | 197 | 199 | 200 | 201 | 206 | 207 | 208 | 210 | 211 | 212 | 213 | 215 | 216 | 217 | 227 | 228 | 229 | 230 | 231 | 233 | 234 | 235 | 236 | 237 | 238 | 241 | 242 | 243 | 246 | 247 | 248 |