├── .gitignore ├── AndroidXamarinChat.sln ├── AndroidXamarinChat ├── ActionListViewAdapter.cs ├── AndroidXamarinChat.csproj ├── AndroidXamarinChat.csproj.DotSettings ├── Assets │ └── AboutAssets.txt ├── ChatActionBarDrawerToggle.cs ├── ChatCmdReceiver.cs ├── ChatDtos.dtos.cs ├── EventReceivers.cs ├── Extensions.cs ├── LoginActivity.cs ├── MainActivity.cs ├── MessageListViewAdapter.cs ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.designer.cs │ ├── color │ │ ├── chat_list_drawable.xml │ │ ├── drawer_item.xml │ │ └── drawer_item_bg.xml │ ├── drawable-hdpi │ │ ├── ic_build_black_24dp.png │ │ ├── ic_discuss.png │ │ ├── ic_done.png │ │ ├── ic_no_profile.png │ │ ├── ic_plus_circle_white_24dp.png │ │ ├── ic_stat_icon.png │ │ └── ic_twitter_logo_blue.png │ ├── drawable-mdpi │ │ ├── ic_build_black_24dp.png │ │ ├── ic_discuss.png │ │ ├── ic_done.png │ │ ├── ic_no_profile.png │ │ ├── ic_plus_circle_white_24dp.png │ │ ├── ic_stat_icon.png │ │ └── ic_twitter_logo_blue.png │ ├── drawable-xhdpi │ │ ├── ic_build_black_24dp.png │ │ ├── ic_discuss.png │ │ ├── ic_done.png │ │ ├── ic_no_profile.png │ │ ├── ic_plus_circle_white_24dp.png │ │ ├── ic_stat_icon.png │ │ └── ic_twitter_logo_blue.png │ ├── drawable-xxhdpi │ │ ├── ic_build_black_24dp.png │ │ ├── ic_discuss.png │ │ ├── ic_done.png │ │ ├── ic_no_profile.png │ │ ├── ic_plus_circle_white_24dp.png │ │ ├── ic_stat_icon.png │ │ ├── ic_twitter_logo_blue.png │ │ └── nav_logo.png │ ├── drawable-xxxhdpi │ │ ├── ic_build_black_24dp.png │ │ ├── ic_done.png │ │ ├── ic_no_profile.png │ │ ├── ic_plus_circle_white_24dp.png │ │ ├── ic_stat_icon.png │ │ ├── ic_twitter_logo_blue.png │ │ └── nav_logo.png │ ├── drawable │ │ ├── circular.xml │ │ └── plus_circle.xml │ ├── layout │ │ ├── Main.axml │ │ ├── action_row_item.axml │ │ ├── chat_message_item.axml │ │ ├── login.axml │ │ └── nav_header.xml │ ├── menu │ │ ├── action_menu.xml │ │ └── drawer_view.xml │ ├── mipmap-hdpi │ │ ├── Icon.png │ │ ├── ic_action_help.png │ │ └── ic_launcher.png │ ├── mipmap-mdpi │ │ ├── Icon.png │ │ ├── ic_action_help.png │ │ └── ic_launcher.png │ ├── mipmap-xhdpi │ │ ├── Icon.png │ │ ├── ic_action_help.png │ │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ │ ├── Icon.png │ │ ├── ic_action_help.png │ │ ├── ic_action_refresh.png │ │ ├── ic_launcher.png │ │ └── ic_menu.png │ ├── mipmap-xxxhdpi │ │ ├── ic_action_help.png │ │ ├── ic_launcher.png │ │ ├── logo_blue.png │ │ ├── logo_transparent.png │ │ └── logo_white_.png │ └── values │ │ ├── Strings.xml │ │ └── styles.xml ├── ServiceStackAuthenticator.cs ├── UIHelpers.cs ├── app.config └── packages.config └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | .vs/ 10 | 11 | # globs 12 | Makefile.in 13 | *.DS_Store 14 | *.sln.cache 15 | *.suo 16 | *.cache 17 | *.pidb 18 | *.userprefs 19 | *.usertasks 20 | config.log 21 | config.make 22 | config.status 23 | aclocal.m4 24 | install-sh 25 | autom4te.cache/ 26 | *.user 27 | *.tar.gz 28 | tarballs/ 29 | test-results/ 30 | Thumbs.db 31 | 32 | #Mac bundle stuff 33 | *.dmg 34 | *.app 35 | 36 | #resharper 37 | *_Resharper.* 38 | *.Resharper 39 | 40 | #dotCover 41 | *.dotCover 42 | 43 | #Xamarin Components 44 | Components/ -------------------------------------------------------------------------------- /AndroidXamarinChat.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2003 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidXamarinChat", "AndroidXamarinChat\AndroidXamarinChat.csproj", "{A5B4D483-38A5-4B91-B7B4-071EE552D718}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 17 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {A5B4D483-38A5-4B91-B7B4-071EE552D718}.Release|Any CPU.Deploy.0 = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ExtensibilityGlobals) = postSolution 25 | SolutionGuid = {2F4FD3BC-801F-43BC-8342-5AA31AE526A0} 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /AndroidXamarinChat/ActionListViewAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Android.App; 7 | using Android.Content; 8 | using Android.OS; 9 | using Android.Runtime; 10 | using Android.Views; 11 | using Android.Widget; 12 | 13 | namespace AndroidXamarinChat 14 | { 15 | public class ActionListViewAdapter : BaseAdapter 16 | { 17 | private readonly Context context; 18 | private readonly List items; 19 | 20 | public ActionListViewAdapter(Context context, List items) 21 | { 22 | this.context = context; 23 | this.items = items; 24 | } 25 | 26 | public override long GetItemId(int position) 27 | { 28 | return position; 29 | } 30 | 31 | public override View GetView(int position, View convertView, ViewGroup parent) 32 | { 33 | View row = convertView; 34 | if (row == null) 35 | row = LayoutInflater.From(context).Inflate(Resource.Layout.action_row_item, null, false); 36 | var label = row.FindViewById(Resource.Id.actionLabel); 37 | label.Text = items[position]; 38 | return row; 39 | } 40 | 41 | public override int Count 42 | { 43 | get { return items.Count; } 44 | } 45 | 46 | public override string this[int position] 47 | { 48 | get { return items[position]; } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /AndroidXamarinChat/AndroidXamarinChat.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 7 | {A5B4D483-38A5-4B91-B7B4-071EE552D718} 8 | Library 9 | AndroidXamarinChat 10 | True 11 | Resources\Resource.designer.cs 12 | Resource 13 | Resources 14 | Assets 15 | AndroidXamarinChat 16 | Properties\AndroidManifest.xml 17 | v9.0 18 | 915687c692385e0d101fdd66982ba723aa67baf3 19 | 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug 27 | DEBUG; 28 | prompt 29 | 4 30 | false 31 | None 32 | 33 | 34 | False 35 | 36 | 37 | 38 | 39 | 40 | 41 | Xamarin 42 | True 43 | default 44 | 45 | 46 | full 47 | true 48 | bin\Release 49 | prompt 50 | 4 51 | false 52 | false 53 | 54 | 55 | 56 | ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\netstandard2.1\Microsoft.Bcl.AsyncInterfaces.dll 57 | 58 | 59 | 60 | ..\packages\Microsoft.Extensions.Primitives.5.0.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll 61 | 62 | 63 | 64 | ..\packages\Refractored.PagerSlidingTabStrip.1.1.6\lib\MonoAndroid10\Refractored.PagerSlidingTabStrip.dll 65 | True 66 | 67 | 68 | ..\packages\ServiceStack.Client.5.10.4\lib\netstandard2.0\ServiceStack.Client.dll 69 | 70 | 71 | ..\packages\ServiceStack.HttpClient.5.10.4\lib\netstandard2.0\ServiceStack.HttpClient.dll 72 | 73 | 74 | ..\packages\ServiceStack.Interfaces.5.10.4\lib\netstandard2.0\ServiceStack.Interfaces.dll 75 | 76 | 77 | ..\packages\ServiceStack.Text.5.10.4\lib\netstandard2.0\ServiceStack.Text.dll 78 | 79 | 80 | 81 | ..\packages\System.Buffers.4.5.1\lib\netstandard2.0\System.Buffers.dll 82 | True 83 | 84 | 85 | 86 | 87 | ..\packages\System.Memory.4.5.4\lib\netstandard2.0\System.Memory.dll 88 | True 89 | 90 | 91 | ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll 92 | 93 | 94 | 95 | ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Animated.Vector.Drawable.dll 96 | 97 | 98 | ..\packages\Xamarin.Android.Support.Annotations.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Annotations.dll 99 | 100 | 101 | ..\packages\Xamarin.Android.Support.Compat.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Compat.dll 102 | 103 | 104 | ..\packages\Xamarin.Android.Support.Core.UI.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Core.UI.dll 105 | 106 | 107 | ..\packages\Xamarin.Android.Support.Core.Utils.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Core.Utils.dll 108 | 109 | 110 | ..\packages\Xamarin.Android.Support.Design.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Design.dll 111 | 112 | 113 | ..\packages\Xamarin.Android.Support.Fragment.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Fragment.dll 114 | 115 | 116 | ..\packages\Xamarin.Android.Support.Media.Compat.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Media.Compat.dll 117 | 118 | 119 | ..\packages\Xamarin.Android.Support.Transition.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Transition.dll 120 | 121 | 122 | ..\packages\Xamarin.Android.Support.v4.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.v4.dll 123 | 124 | 125 | ..\packages\Xamarin.Android.Support.v7.AppCompat.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.v7.AppCompat.dll 126 | 127 | 128 | ..\packages\Xamarin.Android.Support.v7.RecyclerView.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.v7.RecyclerView.dll 129 | 130 | 131 | ..\packages\Xamarin.Android.Support.Vector.Drawable.28.0.0.3\lib\monoandroid71\Xamarin.Android.Support.Vector.Drawable.dll 132 | 133 | 134 | ..\Components\xamarin.auth-1.2.3.1\lib\android\Xamarin.Auth.Android.dll 135 | 136 | 137 | ..\Components\rivets-1.0.5.1\lib\android\Rivets.dll 138 | 139 | 140 | ..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Extensions.dll 141 | 142 | 143 | ..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Primitives.dll 144 | 145 | 146 | 147 | ..\packages\Xamarin.Insights.1.12.3\lib\MonoAndroid10\Xamarin.Insights.dll 148 | True 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | AndroidResource 174 | 175 | 176 | AndroidResource 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | Designer 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 1.0.9 215 | False 216 | 217 | 218 | False 219 | 25.1.1.0 220 | 221 | 222 | 1.0.5.1 223 | False 224 | 225 | 226 | False 227 | 25.1.1.0 228 | 229 | 230 | 1.2.3.1 231 | False 232 | 233 | 234 | 235 | 236 | Designer 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | -------------------------------------------------------------------------------- /AndroidXamarinChat/AndroidXamarinChat.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | CSharp50 -------------------------------------------------------------------------------- /AndroidXamarinChat/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /AndroidXamarinChat/ChatActionBarDrawerToggle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Support.Design.Widget; 3 | using Android.Support.V7.App; 4 | using Android.Support.V4.Widget; 5 | using Android.Views; 6 | using Android.Widget; 7 | 8 | namespace AndroidXamarinChat 9 | { 10 | public class ChatActionBarDrawerToggle : ActionBarDrawerToggle 11 | { 12 | private AppCompatActivity hostActivity; 13 | private readonly DrawerLayout drawerLayout; 14 | private int openedResource; 15 | private int closedResource; 16 | 17 | private bool rightIsClosed = true; 18 | private bool leftIsClosed = true; 19 | 20 | public ChatActionBarDrawerToggle(AppCompatActivity host, 21 | DrawerLayout drawerLayout, 22 | Android.Support.V7.Widget.Toolbar toolbar, 23 | int openedResource, 24 | int closedResource) 25 | : base(host, drawerLayout, toolbar, openedResource, closedResource) 26 | { 27 | hostActivity = host; 28 | this.drawerLayout = drawerLayout; 29 | this.openedResource = openedResource; 30 | this.closedResource = closedResource; 31 | } 32 | 33 | public override void OnDrawerOpened(View drawerView) 34 | { 35 | int drawerType = (int)drawerView.Tag; 36 | 37 | if (drawerType == 0) 38 | { 39 | base.OnDrawerOpened(drawerView); 40 | hostActivity.SupportActionBar.SetTitle(openedResource); 41 | } 42 | 43 | if (drawerView.Id == Resource.Id.nav_view) 44 | leftIsClosed = false; 45 | 46 | if (drawerView.Id == Resource.Id.right_drawer) 47 | rightIsClosed = false; 48 | } 49 | 50 | public override void OnDrawerClosed(View drawerView) 51 | { 52 | int drawerType = (int)drawerView.Tag; 53 | 54 | if (drawerType == 0) 55 | { 56 | base.OnDrawerClosed(drawerView); 57 | hostActivity.SupportActionBar.SetTitle(closedResource); 58 | } 59 | 60 | if (drawerView.Id == Resource.Id.nav_view) 61 | leftIsClosed = true; 62 | 63 | if (drawerView.Id == Resource.Id.right_drawer) 64 | rightIsClosed = true; 65 | } 66 | 67 | public override void OnDrawerSlide(View drawerView, float slideOffset) 68 | { 69 | int drawerType = (int)drawerView.Tag; 70 | 71 | var leftDrawer = hostActivity.FindViewById(Resource.Id.nav_view); 72 | var rightDrawer = hostActivity.FindViewById(Resource.Id.right_drawer); 73 | switch (drawerView.Id) 74 | { 75 | case Resource.Id.right_drawer: 76 | if (drawerLayout.IsDrawerOpen(leftDrawer) && !leftIsClosed) 77 | { 78 | drawerLayout.CloseDrawer(leftDrawer); 79 | leftIsClosed = true; 80 | } 81 | break; 82 | case Resource.Id.nav_view: 83 | 84 | if (drawerLayout.IsDrawerOpen(rightDrawer) && !rightIsClosed) 85 | { 86 | drawerLayout.CloseDrawer(rightDrawer); 87 | rightIsClosed = true; 88 | } 89 | break; 90 | } 91 | 92 | if (drawerType == 0) 93 | { 94 | base.OnDrawerSlide(drawerView, slideOffset); 95 | } 96 | } 97 | } 98 | } 99 | 100 | -------------------------------------------------------------------------------- /AndroidXamarinChat/ChatCmdReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.App; 3 | using Android.Widget; 4 | using Chat; 5 | using ServiceStack; 6 | using ServiceStack.Configuration; 7 | using Android.Content; 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | using Android.Graphics; 11 | using Android.Graphics.Drawables; 12 | using Android.OS; 13 | 14 | namespace AndroidXamarinChat 15 | { 16 | public class ChatCommandHandler 17 | { 18 | private MainActivity parentActivity; 19 | private MessageListViewAdapter messageAdapter; 20 | public Dictionary> FullHistory { get; set; } 21 | 22 | public string CurrentChannel { get; set; } 23 | 24 | public ChatCommandHandler(MainActivity parentActivity, MessageListViewAdapter messageAdapter, string initialChannel) 25 | { 26 | this.parentActivity = parentActivity; 27 | this.messageAdapter = messageAdapter; 28 | this.FullHistory = new Dictionary>(); 29 | this.CurrentChannel = initialChannel; 30 | } 31 | 32 | public void AppendMessage(ChatMessage chatMessage) 33 | { 34 | if (!FullHistory.ContainsKey(chatMessage.Channel)) 35 | { 36 | FullHistory.Add(chatMessage.Channel, new List()); 37 | } 38 | FullHistory[chatMessage.Channel].Add(chatMessage); 39 | if (chatMessage.Channel == this.CurrentChannel) 40 | { 41 | Application.SynchronizationContext.Post(_ => 42 | { 43 | messageAdapter.Add(chatMessage); 44 | messageAdapter.NotifyDataSetChanged(); 45 | }, null); 46 | } 47 | } 48 | 49 | public void ChangeChannel(string channel) 50 | { 51 | this.CurrentChannel = channel; 52 | Application.SynchronizationContext.Post(_ => 53 | { 54 | messageAdapter.Clear(); 55 | if (FullHistory.ContainsKey(channel)) 56 | { 57 | FullHistory[channel].ForEach(msg => 58 | { 59 | messageAdapter.Add(msg); 60 | }); 61 | } 62 | }, null); 63 | } 64 | 65 | public void SyncAdapter() 66 | { 67 | ChangeChannel(this.CurrentChannel); 68 | } 69 | 70 | public void ShowVideo(string videoUrl) 71 | { 72 | parentActivity.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(videoUrl))); 73 | } 74 | 75 | public void Announce(string message) 76 | { 77 | Notification.Builder builder = new Notification.Builder(parentActivity) 78 | .SetLocalOnly(true) 79 | .SetAutoCancel(true) 80 | .SetContentTitle("Chat (Xamarin)") 81 | .SetContentText(message) 82 | .SetSmallIcon(Resource.Drawable.ic_stat_icon); 83 | 84 | // Build the notification: 85 | Notification notification = builder.Build(); 86 | 87 | // Get the notification manager: 88 | NotificationManager notificationManager = 89 | parentActivity.GetSystemService(Context.NotificationService) as NotificationManager; 90 | 91 | // Publish the notification: 92 | const int notificationId = 0; 93 | if (notificationManager != null) 94 | { 95 | notificationManager.Notify(notificationId, notification); 96 | 97 | Vibrator vibrator = (Vibrator)parentActivity.GetSystemService(Context.VibratorService); 98 | vibrator.Vibrate(1000); 99 | CancelNotification(notificationManager).ConfigureAwait(false); 100 | } 101 | } 102 | 103 | private async Task CancelNotification(NotificationManager notificationManager) 104 | { 105 | await Task.Delay(5000); 106 | notificationManager.CancelAll(); 107 | } 108 | 109 | public void ChangeBackground(string message) 110 | { 111 | var url = message.StartsWith("url(") ? message.Substring(4, message.Length - 5) : message; 112 | url.GetImageBitmap().ContinueWith(t => 113 | { 114 | var bitmap = t.Result; 115 | var chatBackground = parentActivity.FindViewById(Resource.Id.chat_background); 116 | Application.SynchronizationContext.Post(_ => 117 | { 118 | chatBackground.SetImageBitmap(bitmap); 119 | }, null); 120 | }); 121 | } 122 | 123 | public void ChangeBackgroundColor(string message, string cssSelector) 124 | { 125 | // Inject alpha values 126 | string color = message.Replace("#", "#AA"); 127 | var chatLayout = parentActivity.FindViewById(Resource.Id.messageHistory); 128 | var editText = parentActivity.FindViewById(Resource.Id.message); 129 | var sendButton = parentActivity.FindViewById