rename folder keepass2android => keepass2android-app
This commit is contained in:
		
							
								
								
									
										44
									
								
								src/keepass2android-app/views/ClickView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/keepass2android-app/views/ClickView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
|  | ||||
| using System; | ||||
| using Android.Content; | ||||
| using Android.Runtime; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
| 	public abstract class ClickView : LinearLayout { | ||||
| 		protected ClickView (IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
| 			 | ||||
| 		} | ||||
|  | ||||
| 		protected ClickView(Context context) :base(context) | ||||
| 		{ | ||||
| 		} | ||||
| 		 | ||||
| 		abstract public void OnClick(); | ||||
| 		 | ||||
| 		abstract public void OnCreateMenu(IContextMenu menu, IContextMenuContextMenuInfo menuInfo); | ||||
| 		 | ||||
| 		abstract public bool OnContextItemSelected(IMenuItem item); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										64
									
								
								src/keepass2android-app/views/EntryContentsView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/keepass2android-app/views/EntryContentsView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
|  | ||||
| using Android.Content; | ||||
| using Android.Util; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
|  | ||||
| using System; | ||||
| using Android.Runtime; | ||||
| using keepass2android; | ||||
|  | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
| 	 | ||||
| 	public class EntryContentsView : LinearLayout { | ||||
|  | ||||
| 		public EntryContentsView (IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		public EntryContentsView(Context context):base(context, null) { | ||||
| 			InflateView(); | ||||
| 		} | ||||
| 		 | ||||
| 		public EntryContentsView(Context context, IAttributeSet attrs): base(context, attrs) { | ||||
| 			 | ||||
| 			InflateView(); | ||||
| 		} | ||||
| 		 | ||||
| 		private void InflateView() { | ||||
| 			LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService); | ||||
| 			inflater.Inflate(Resource.Layout.entry_view_contents, this); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		/* | ||||
| 		 * doesn't compile with mono for android | ||||
| 		 *  | ||||
| 		protected override LayoutParams GenerateDefaultLayoutParams() { | ||||
| 			return new LayoutParams(LayoutParams.FillParent, LayoutParams.WrapContent); | ||||
| 		} | ||||
| 		*/ | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										75
									
								
								src/keepass2android-app/views/EntrySection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/keepass2android-app/views/EntrySection.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
|  | ||||
| using System; | ||||
| using Android.Content; | ||||
| using Android.Runtime; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using Android.Util; | ||||
| using keepass2android; | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
| 	 | ||||
| 	public class EntrySection : LinearLayout { | ||||
| 		 | ||||
| 		public EntrySection(Context context): base(context, null) { | ||||
| 			InflateView (null, null); | ||||
| 		} | ||||
| 		 | ||||
| 		public EntrySection(Context context, IAttributeSet attrs): base(context, attrs) { | ||||
| 			InflateView (null, null); | ||||
| 		} | ||||
| 		 | ||||
| 		public EntrySection(Context context, IAttributeSet attrs, String title, String value): base(context, attrs) { | ||||
| 			 | ||||
| 			InflateView(title, value); | ||||
| 		} | ||||
|  | ||||
| 		public EntrySection (IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
| 			 | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		private void InflateView(String title, String value) { | ||||
| 			LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService); | ||||
| 			inflater.Inflate(Resource.Layout.entry_section, this); | ||||
| 			 | ||||
| 			SetText(Resource.Id.title, title); | ||||
|  | ||||
| 			FindViewById<TextView>(Resource.Id.value).Invalidate(); | ||||
| 			SetText(Resource.Id.value, value); | ||||
| 			//TODO: this seems to cause a bug when rotating the device (and the activity gets destroyed) | ||||
| 			//After recreating the activity, the value fields all have the same content. | ||||
| 			if ((int)Android.OS.Build.VERSION.SdkInt >= 11) | ||||
| 				FindViewById<TextView>(Resource.Id.value).SetTextIsSelectable(true); | ||||
| 		} | ||||
| 		 | ||||
| 		private void SetText(int resId, String str) { | ||||
| 			if (str != null) { | ||||
| 				TextView tvTitle = (TextView) FindViewById(resId); | ||||
| 				tvTitle.Text = str; | ||||
| 			} | ||||
| 			 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										71
									
								
								src/keepass2android-app/views/GroupListItemView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/keepass2android-app/views/GroupListItemView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| using System; | ||||
| using Android.Content; | ||||
| using Android.Runtime; | ||||
| using Android.Util; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using keepass2android; | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
|     public abstract class GroupListItemView : LinearLayout | ||||
|     { | ||||
|         protected readonly GroupBaseActivity _groupBaseActivity; | ||||
|  | ||||
|         protected GroupListItemView(IntPtr javaReference, JniHandleOwnership transfer) | ||||
|             : base(javaReference, transfer) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public GroupListItemView(GroupBaseActivity context) | ||||
|             : base(context) | ||||
|         { | ||||
|             _groupBaseActivity = context; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public GroupListItemView(Context context, IAttributeSet attrs) | ||||
|             : base(context, attrs) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public GroupListItemView(Context context, IAttributeSet attrs, int defStyleAttr) | ||||
|             : base(context, attrs, defStyleAttr) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public GroupListItemView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) | ||||
|             : base(context, attrs, defStyleAttr, defStyleRes) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public override bool Activated | ||||
|         { | ||||
|             get { return base.Activated; } | ||||
|             set | ||||
|             { | ||||
|                 if (value) | ||||
|                 { | ||||
|                     FindViewById(Resource.Id.icon).Visibility = ViewStates.Invisible; | ||||
|                     FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Visible; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible; | ||||
|                     FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible; | ||||
|                 } | ||||
|  | ||||
|                 base.Activated = value; | ||||
|             } | ||||
|         } | ||||
|  | ||||
| 	    public void SetRightArrowVisibility(bool visible) | ||||
| 	    { | ||||
| 			FindViewById(Resource.Id.right_arrow).Visibility = visible ? ViewStates.Visible : ViewStates.Invisible; | ||||
| 	    } | ||||
|  | ||||
|         public abstract void OnClick(); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										106
									
								
								src/keepass2android-app/views/Kp2aShortHelpView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/keepass2android-app/views/Kp2aShortHelpView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| using Android.App; | ||||
| using Android.Content; | ||||
| using Android.Content.Res; | ||||
| using Android.Graphics; | ||||
| using Android.OS; | ||||
| using Android.Runtime; | ||||
| using Android.Text; | ||||
| using Android.Text.Method; | ||||
| using Android.Text.Style; | ||||
| using Android.Text.Util; | ||||
| using Android.Util; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using Google.Android.Material.Dialog; | ||||
| using keepass2android; | ||||
|  | ||||
| namespace keepass2android.views | ||||
| { | ||||
| 	public class Kp2aShortHelpView: TextView | ||||
| 	{ | ||||
| 		private string _helpText; | ||||
| 		private static Typeface _iconFont; | ||||
|  | ||||
| 		protected Kp2aShortHelpView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		public Kp2aShortHelpView(Context context) : base(context) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		public Kp2aShortHelpView(Context context, IAttributeSet attrs) : base(context, attrs) | ||||
| 		{ | ||||
| 			Initialize(attrs); | ||||
| 		} | ||||
|  | ||||
| 		public Kp2aShortHelpView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) | ||||
| 		{ | ||||
| 			Initialize(attrs); | ||||
| 		} | ||||
|  | ||||
| 		public string HelpText | ||||
| 		{ | ||||
| 			get { return _helpText; } | ||||
| 			set { _helpText = value; | ||||
| 				UpdateView(); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		public string TitleText { get; set; } | ||||
|  | ||||
| 		private void UpdateView() | ||||
| 		{ | ||||
| 			if (!String.IsNullOrEmpty(_helpText)) | ||||
| 			{ | ||||
| 				Text = Context.GetString(Resource.String.icon_info); | ||||
| 				Clickable = true; | ||||
|  | ||||
|  | ||||
| 				if (_iconFont == null) | ||||
| 					_iconFont = Typeface.CreateFromAsset(Context.Assets, "fontawesome-webfont.ttf"); | ||||
|  | ||||
| 				System.Diagnostics.Debug.Assert(_iconFont != null, "_iconFont != null"); | ||||
|  | ||||
| 				SetTypeface(_iconFont, TypefaceStyle.Normal); | ||||
| 				//TextFormatted = Html.FromHtml("<a>" + Text + "</a>"); | ||||
| 				//var spannableString = new SpannableString(Text); | ||||
| 				//spannableString.SetSpan(new UnderlineSpan(), 0, Text.Length, SpanTypes.ExclusiveExclusive); | ||||
| 				//TextFormatted = spannableString; | ||||
|  | ||||
| 				MovementMethod = LinkMovementMethod.Instance; | ||||
| 				Click += (sender, args) => | ||||
| 				{ | ||||
| 					string title = Context.GetString(AppNames.AppNameResource); | ||||
| 					if (!string.IsNullOrEmpty(TitleText)) | ||||
| 						title = TitleText; | ||||
| 					new MaterialAlertDialogBuilder(Context) | ||||
| 						.SetTitle(title) | ||||
| 						.SetMessage(_helpText) | ||||
| 						.SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { }) | ||||
| 					.Show(); | ||||
| 				}; | ||||
| 				Visibility = ViewStates.Visible; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				Visibility = ViewStates.Gone; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		void Initialize(IAttributeSet attrs) | ||||
| 		{ | ||||
| 			TypedArray a = Context.ObtainStyledAttributes( | ||||
| 		 attrs, | ||||
| 		 Resource.Styleable.Kp2aShortHelpView); | ||||
| 			TitleText = a.GetString(Resource.Styleable.Kp2aShortHelpView_title_text); | ||||
| 			HelpText = a.GetString(Resource.Styleable.Kp2aShortHelpView_help_text); | ||||
| 		 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										317
									
								
								src/keepass2android-app/views/PwEntryView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								src/keepass2android-app/views/PwEntryView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,317 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using Android.Graphics; | ||||
| using Android.OS; | ||||
| using Android.Runtime; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using KeePassLib; | ||||
| using Android.Text; | ||||
| using Android.Text.Style; | ||||
| using Android.Preferences; | ||||
| using KeePass.Util.Spr; | ||||
| using KeeTrayTOTP.Libraries; | ||||
| using PluginTOTP; | ||||
| using Android.Content; | ||||
| using System.ComponentModel; | ||||
| using keepass2android; | ||||
|  | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
| 	public sealed class PwEntryView : GroupListItemView | ||||
| 	{ | ||||
| 		private readonly GroupBaseActivity _groupActivity; | ||||
| 		private PwEntry _entry; | ||||
| 		private readonly TextView _textView; | ||||
| 		private readonly TextView _textviewDetails; | ||||
| 		private readonly TextView _textgroupFullPath; | ||||
|         private readonly ProgressBar _totpCountdown; | ||||
|         private readonly TextView _totpText; | ||||
|         private readonly LinearLayout _totpLayout; | ||||
|  | ||||
|         private int _pos; | ||||
|  | ||||
| 		private int? _defaultTextColor; | ||||
|  | ||||
| 		readonly bool _showDetail; | ||||
| 		readonly bool _showGroupFullPath; | ||||
| 		readonly bool _isSearchResult; | ||||
|  | ||||
|  | ||||
| 		private const int MenuOpen = Menu.First; | ||||
| 		private const int MenuDelete = MenuOpen + 1; | ||||
| 		private const int MenuMove = MenuDelete + 1; | ||||
| 		private const int MenuNavigate = MenuMove + 1; | ||||
| 		 | ||||
| 		public static PwEntryView GetInstance(GroupBaseActivity act, PwEntry pw, int pos) | ||||
| 		{ | ||||
| 			return new PwEntryView(act, pw, pos); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		public PwEntryView(IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
| 			 | ||||
| 		} | ||||
|  | ||||
| 		private PwEntryView(GroupBaseActivity groupActivity, PwEntry pw, int pos):base(groupActivity) | ||||
| 		{ | ||||
| 			_groupActivity = groupActivity; | ||||
|  | ||||
|             View ev = Inflate(groupActivity, Resource.Layout.entry_list_entry, null); | ||||
| 			_textView = (TextView)ev.FindViewById(Resource.Id.entry_text); | ||||
| 			_textView.TextSize = PrefsUtil.GetListTextSize(groupActivity); | ||||
|  | ||||
| 		    Database db = App.Kp2a.FindDatabaseForElement(pw); | ||||
| 			 | ||||
| 			ev.FindViewById(Resource.Id.entry_icon_bkg).Visibility = db.DrawableFactory.IsWhiteIconSet ?  ViewStates.Visible : ViewStates.Gone; | ||||
|  | ||||
| 			_textviewDetails = (TextView)ev.FindViewById(Resource.Id.entry_text_detail); | ||||
| 			_textviewDetails.TextSize = PrefsUtil.GetListDetailTextSize(groupActivity); | ||||
|  | ||||
| 			_textgroupFullPath = (TextView)ev.FindViewById(Resource.Id.group_detail); | ||||
| 			_textgroupFullPath.TextSize = PrefsUtil.GetListDetailTextSize(groupActivity); | ||||
|  | ||||
|             _totpCountdown = ev.FindViewById<ProgressBar>(Resource.Id.TotpCountdownProgressBar); | ||||
|             _totpText = ev.FindViewById<TextView>(Resource.Id.totp_text); | ||||
|             _totpLayout = ev.FindViewById<LinearLayout>(Resource.Id.totp_layout); | ||||
|  | ||||
|             _totpLayout.LongClick += (sender, args) => | ||||
|             { | ||||
|                 string totp = UpdateTotp(); | ||||
|                 if (!String.IsNullOrEmpty(totp)) | ||||
|                     CopyToClipboardService.CopyValueToClipboardWithTimeout(_groupActivity, totp, true); | ||||
|             }; | ||||
|  | ||||
|             _showDetail = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean( | ||||
| 				groupActivity.GetString(Resource.String.ShowUsernameInList_key),  | ||||
| 				Resources.GetBoolean(Resource.Boolean.ShowUsernameInList_default)); | ||||
|  | ||||
| 			_showGroupFullPath = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean( | ||||
| 				groupActivity.GetString(Resource.String.ShowGroupnameInSearchResult_key),  | ||||
| 				Resources.GetBoolean(Resource.Boolean.ShowGroupnameInSearchResult_default)); | ||||
|  | ||||
| 			_isSearchResult = _groupActivity is keepass2android.search.SearchResults; | ||||
|  | ||||
|  | ||||
| 			PopulateView(ev, pw, pos); | ||||
| 			 | ||||
| 			LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent); | ||||
| 			 | ||||
| 			AddView(ev, lp); | ||||
| 			 | ||||
| 		} | ||||
| 		 | ||||
| 		private void PopulateView(View ev, PwEntry pw, int pos) | ||||
| 		{ | ||||
|  | ||||
|             if (_groupBaseActivity.IsFinishing) | ||||
|                 return; | ||||
|  | ||||
|             _entry = pw; | ||||
| 			_pos = pos; | ||||
| 		    ev.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible; | ||||
| 		    ev.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible; | ||||
|  | ||||
| 		    _db = App.Kp2a.FindDatabaseForElement(_entry); | ||||
|  | ||||
|             ImageView iv = (ImageView)ev.FindViewById(Resource.Id.icon); | ||||
| 			bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now; | ||||
| 			if (isExpired) | ||||
| 			{ | ||||
| 				_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false); | ||||
| 			} else | ||||
| 			{ | ||||
| 				_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, pw.IconId, pw.CustomIconUuid, false); | ||||
| 			} | ||||
|  | ||||
| 			String title = pw.Strings.ReadSafe(PwDefs.TitleField); | ||||
|             title = SprEngine.Compile(title, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All)); | ||||
|             var str = new SpannableString(title); | ||||
|  | ||||
| 			if (isExpired) | ||||
| 			{ | ||||
| 				str.SetSpan(new StrikethroughSpan(), 0, title.Length, SpanTypes.ExclusiveExclusive); | ||||
| 			} | ||||
| 			_textView.TextFormatted = str; | ||||
|  | ||||
| 			if (_defaultTextColor == null) | ||||
| 				_defaultTextColor = _textView.TextColors.DefaultColor; | ||||
|  | ||||
| 			if (_groupActivity.IsBeingMoved(_entry.Uuid)) | ||||
| 			{ | ||||
| 				int elementBeingMoved = Context.Resources.GetColor(Resource.Color.md_theme_inversePrimary); | ||||
| 				_textView.SetTextColor(new Color(elementBeingMoved)); | ||||
| 			} | ||||
| 			else | ||||
| 				_textView.SetTextColor(new Color((int)_defaultTextColor)); | ||||
|  | ||||
| 			String detail = pw.Strings.ReadSafe(PwDefs.UserNameField); | ||||
| 			detail = SprEngine.Compile(detail, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All)); | ||||
|  | ||||
| 			if ((_showDetail == false) || (String.IsNullOrEmpty(detail))) | ||||
| 			{ | ||||
| 				_textviewDetails.Visibility = ViewStates.Gone; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				var strDetail = new SpannableString(detail); | ||||
| 				 | ||||
| 				if (isExpired) | ||||
| 				{ | ||||
| 					strDetail.SetSpan(new StrikethroughSpan(), 0, detail.Length, SpanTypes.ExclusiveExclusive); | ||||
| 				} | ||||
| 				_textviewDetails.TextFormatted = strDetail; | ||||
|  | ||||
| 				_textviewDetails.Visibility = ViewStates.Visible; | ||||
| 			} | ||||
| 				 | ||||
| 			if ( (!_showGroupFullPath) || (!_isSearchResult) ) { | ||||
| 				_textgroupFullPath.Visibility = ViewStates.Gone; | ||||
| 			} | ||||
|  | ||||
| 			else { | ||||
| 				String groupDetail = pw.ParentGroup.GetFullPath(); | ||||
| 			    if (App.Kp2a.OpenDatabases.Count() > 1) | ||||
| 			    { | ||||
| 			        groupDetail += "(" + App.Kp2a.GetFileStorage(_db.Ioc).GetDisplayName(_db.Ioc) + ")"; | ||||
| 			    } | ||||
|  | ||||
| 				var strGroupDetail = new SpannableString (groupDetail); | ||||
|  | ||||
| 				if (isExpired) { | ||||
| 					strGroupDetail.SetSpan (new StrikethroughSpan (), 0, groupDetail.Length, SpanTypes.ExclusiveExclusive); | ||||
| 				} | ||||
| 				_textgroupFullPath.TextFormatted = strGroupDetail; | ||||
|  | ||||
| 				_textgroupFullPath.Visibility = ViewStates.Visible; | ||||
| 			} | ||||
|  | ||||
| 			//try to get totp data | ||||
|             UpdateTotp(); | ||||
|              | ||||
|  | ||||
|             | ||||
|                  | ||||
|  | ||||
|              | ||||
|  | ||||
|         } | ||||
| 		 | ||||
| 		public void ConvertView(PwEntry pw, int pos) | ||||
| 		{ | ||||
| 			PopulateView(this, pw, pos); | ||||
| 		} | ||||
|  | ||||
| 		 | ||||
| 		private void LaunchEntry() | ||||
| 		{ | ||||
| 			_groupActivity.LaunchActivityForEntry(_entry, _pos); | ||||
| 			//_groupActivity.OverridePendingTransition(Resource.Animation.anim_enter, Resource.Animation.anim_leave); | ||||
| 		} | ||||
| 		/* | ||||
| 		public override void OnCreateMenu(IContextMenu menu, IContextMenuContextMenuInfo menuInfo) | ||||
| 		{ | ||||
| 			menu.Add(0, MenuOpen, 0, Resource.String.menu_open); | ||||
| 			if (App.Kp2a.GetDb().CanWrite) | ||||
| 			{ | ||||
| 				menu.Add(0, MenuDelete, 0, Resource.String.menu_delete); | ||||
| 				menu.Add(0, MenuMove, 0, Resource.String.menu_move); | ||||
|  | ||||
| 				if (_isSearchResult) { | ||||
| 					menu.Add (0, MenuNavigate, 0, Resource.String.menu_navigate); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		public override bool OnContextItemSelected(IMenuItem item) | ||||
| 		{ | ||||
| 			switch (item.ItemId) | ||||
| 			{ | ||||
| 				 | ||||
| 				case MenuOpen: | ||||
| 					LaunchEntry(); | ||||
| 					return true; | ||||
| 				case MenuDelete: | ||||
| 					Handler handler = new Handler(); | ||||
| 					DeleteEntry task = new DeleteEntry(Context, App.Kp2a, _entry, new GroupBaseActivity.RefreshTask(handler, _groupActivity)); | ||||
| 					task.Start(); | ||||
| 					return true; | ||||
| 				case MenuMove: | ||||
| 					NavigateToFolderAndLaunchMoveElementTask navMove =  | ||||
| 						new NavigateToFolderAndLaunchMoveElementTask(_entry.ParentGroup, _entry.Uuid, _isSearchResult); | ||||
| 					_groupActivity.StartTask (navMove); | ||||
| 					return true; | ||||
| 				case MenuNavigate:  | ||||
| 					NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true); | ||||
| 					_groupActivity.StartTask (navNavigate); | ||||
| 					return true; | ||||
|  | ||||
| 				default: | ||||
| 					return false; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		*/ | ||||
| 	    public override void OnClick() | ||||
| 	    { | ||||
| 	        LaunchEntry(); | ||||
| 	    } | ||||
|  | ||||
|          | ||||
|          | ||||
|         private TotpData _totpData; | ||||
| 		 | ||||
|         private Database _db; | ||||
|  | ||||
|         public string UpdateTotp() | ||||
|         { | ||||
|             ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(_groupActivity); | ||||
|             bool showTotpDefault = _groupActivity.MayPreviewTotp; | ||||
|                  | ||||
|  | ||||
|             if (showTotpDefault) | ||||
|                 _totpData = new Kp2aTotp().TryGetTotpData(new PwEntryOutput(_entry, _db)); | ||||
| 			else | ||||
| 			    _totpData = null; | ||||
|  | ||||
|             if (_totpData?.IsTotpEntry != true) | ||||
|             { | ||||
|                 _totpLayout.Visibility = ViewStates.Gone; | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             _totpLayout.Visibility = ViewStates.Visible; | ||||
|  | ||||
|             TOTPProvider prov = new TOTPProvider(_totpData); | ||||
|             string totp = prov.GenerateByByte(_totpData.TotpSecret); | ||||
|  | ||||
|             _totpText.Text = totp; | ||||
|             var progressBar = _totpCountdown; | ||||
|             progressBar.Progress = prov.Timer; | ||||
|             progressBar.Max = prov.Duration; | ||||
|  | ||||
|             return totp; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										203
									
								
								src/keepass2android-app/views/PwGroupView.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/keepass2android-app/views/PwGroupView.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
|  | ||||
| using System; | ||||
| using Android.Graphics; | ||||
| using Android.OS; | ||||
| using Android.Runtime; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using keepass2android; | ||||
| using KeePassLib; | ||||
| using Object = Java.Lang.Object; | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
|  | ||||
|     public sealed class PwGroupView : GroupListItemView  | ||||
| 	{ | ||||
| 		private PwGroup _pwGroup; | ||||
| 		private readonly GroupBaseActivity _groupBaseActivity; | ||||
| 		private readonly TextView _textview, _label; | ||||
| 		private int? _defaultTextColor; | ||||
|  | ||||
| 		private const int MenuOpen = Menu.First; | ||||
| 		private const int MenuDelete = MenuOpen + 1; | ||||
| 		private const int MenuMove = MenuDelete + 1; | ||||
| 		private const int MenuEdit = MenuDelete + 2; | ||||
| 		 | ||||
| 		public static PwGroupView GetInstance(GroupBaseActivity act, PwGroup pw) { | ||||
|  | ||||
| 			return new PwGroupView(act, pw); | ||||
|  | ||||
| 		} | ||||
| 		public PwGroupView (IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
| 			 | ||||
| 		} | ||||
|  | ||||
| 		private PwGroupView(GroupBaseActivity act, PwGroup pw) | ||||
| 		: base(act){ | ||||
| 			_groupBaseActivity = act; | ||||
| 			 | ||||
| 			View gv = Inflate(act, Resource.Layout.group_list_entry, null); | ||||
| 			 | ||||
| 			_textview = (TextView) gv.FindViewById(Resource.Id.group_text); | ||||
| 			float size = PrefsUtil.GetListTextSize(act);  | ||||
| 			_textview.TextSize = size; | ||||
| 			 | ||||
| 			_label = (TextView) gv.FindViewById(Resource.Id.group_label); | ||||
| 			_label.TextSize = size-8; | ||||
|  | ||||
| 		    Database db = App.Kp2a.FindDatabaseForElement(pw); | ||||
|  | ||||
|             gv.FindViewById(Resource.Id.group_icon_bkg).Visibility = db.DrawableFactory.IsWhiteIconSet ? ViewStates.Visible : ViewStates.Gone; | ||||
|  | ||||
| 		    gv.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible; | ||||
| 		    gv.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible; | ||||
|  | ||||
|             PopulateView(gv, pw); | ||||
| 			 | ||||
| 			LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent); | ||||
| 			 | ||||
| 			AddView(gv, lp); | ||||
| 		} | ||||
| 		 | ||||
| 		private void PopulateView(View gv, PwGroup pw) | ||||
|         { | ||||
| 			_pwGroup = pw; | ||||
|  | ||||
|             if (_groupBaseActivity.IsFinishing) | ||||
|                 return; | ||||
|  | ||||
|             ImageView iv = (ImageView) gv.FindViewById(Resource.Id.icon); | ||||
| 		    Database db = App.Kp2a.FindDatabaseForElement(pw); | ||||
|             db.DrawableFactory.AssignDrawableTo(iv, _groupBaseActivity, db.KpDatabase, pw.IconId, pw.CustomIconUuid, true); | ||||
| 		    gv.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible; | ||||
| 		    gv.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible; | ||||
|  | ||||
|  | ||||
|             _textview.Text = pw.Name; | ||||
|  | ||||
| 			if (_defaultTextColor == null) | ||||
| 				_defaultTextColor = _textview.TextColors.DefaultColor; | ||||
|  | ||||
| 			if (_groupBaseActivity.IsBeingMoved(_pwGroup.Uuid)) | ||||
| 			{ | ||||
| 				int elementBeingMoved = Context.Resources.GetColor(Resource.Color.md_theme_inversePrimary); | ||||
| 				_textview.SetTextColor(new Color(elementBeingMoved)); | ||||
| 			} | ||||
| 			else | ||||
| 				_textview.SetTextColor(new Color((int)_defaultTextColor)); | ||||
|  | ||||
| 			_label.Text = _groupBaseActivity.GetString (Resource.String.group)+" - "; | ||||
|             uint numEntries = CountEntries (pw); | ||||
| 		    if (numEntries == 1) | ||||
| 		        _label.Text += Context.GetString(Resource.String.Entry_singular); | ||||
| 		    else | ||||
| 		    { | ||||
| 		        Java.Lang.Object obj = (int)numEntries; | ||||
| 		        _label.Text += Context.GetString(Resource.String.Entry_plural, obj); | ||||
|             } | ||||
| 				 | ||||
| 		} | ||||
|  | ||||
| 		uint CountEntries(PwGroup g) | ||||
| 		{ | ||||
| 			uint n = g.Entries.UCount; | ||||
|  | ||||
| 			foreach (PwGroup subgroup in g.Groups)  | ||||
| 			{ | ||||
| 				n += CountEntries(subgroup); | ||||
| 			} | ||||
|  | ||||
| 			return n; | ||||
| 		} | ||||
| 		 | ||||
| 		public void ConvertView(PwGroup pw) { | ||||
| 			PopulateView(this, pw); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		private void LaunchGroup() { | ||||
| 			GroupActivity.Launch(_groupBaseActivity, _pwGroup, _groupBaseActivity.AppTask, new ActivityLaunchModeRequestCode(0)); | ||||
| 			//_groupBaseActivity.OverridePendingTransition(Resource.Animation.anim_enter, Resource.Animation.anim_leave); | ||||
|  | ||||
| 		} | ||||
|         /* | ||||
| 		public override void OnCreateMenu(IContextMenu menu, IContextMenuContextMenuInfo menuInfo) { | ||||
| 			menu.Add(0, MenuOpen, 0, Resource.String.menu_open); | ||||
| 			if (App.Kp2a.GetDb().CanWrite) | ||||
| 			{ | ||||
| 				menu.Add(0, MenuDelete, 0, Resource.String.menu_delete); | ||||
| 				menu.Add(0, MenuMove, 0, Resource.String.menu_move); | ||||
| 				menu.Add(0, MenuEdit, 0, Resource.String.menu_edit); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		public override bool OnContextItemSelected(IMenuItem item)  | ||||
| 		{ | ||||
| 			switch ( item.ItemId ) { | ||||
| 				case MenuOpen: | ||||
| 					LaunchGroup(); | ||||
| 					return true; | ||||
| 			 | ||||
| 				case MenuDelete: | ||||
| 					Handler handler = new Handler(); | ||||
| 					DeleteGroup task = new DeleteGroup(Context, App.Kp2a, _pwGroup, new GroupBaseActivity.AfterDeleteGroup(handler, _groupBaseActivity)); | ||||
| 					task.Start(); | ||||
| 					return true; | ||||
| 				case MenuMove: | ||||
| 					_groupBaseActivity.StartTask(new MoveElementsTask { Uuid = _pwGroup.Uuid }); | ||||
| 					return true; | ||||
| 				case MenuEdit: | ||||
| 					_groupBaseActivity.EditGroup(_pwGroup); | ||||
| 					return true; | ||||
| 				default: | ||||
| 					return false; | ||||
| 			} | ||||
| 		}*/ | ||||
|  | ||||
|         public override void OnClick() | ||||
|         { | ||||
|             LaunchGroup(); | ||||
|         } | ||||
| 	} | ||||
|  | ||||
|      | ||||
|     internal class JavaObjectAdapter : Java.Lang.Object | ||||
|     { | ||||
|         private readonly uint _value; | ||||
|         public JavaObjectAdapter(uint value) | ||||
|         { | ||||
|             _value = value; | ||||
|         } | ||||
|  | ||||
|         public JavaObjectAdapter(System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) | ||||
|             : base(handle, transfer) | ||||
|         { | ||||
|              | ||||
|         } | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             return _value.ToString(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										84
									
								
								src/keepass2android-app/views/TextViewSelect.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/keepass2android-app/views/TextViewSelect.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* | ||||
| This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin. | ||||
|  | ||||
|   Keepass2Android is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Keepass2Android is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Keepass2Android.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   */ | ||||
| using System; | ||||
| using Android.Content; | ||||
| using Android.Runtime; | ||||
| using Android.Widget; | ||||
| using Android.Text.Method; | ||||
| using Android.Util; | ||||
| using Java.Lang; | ||||
|  | ||||
| namespace keepass2android.view | ||||
| { | ||||
| 	 | ||||
| 	public class TextViewSelect : TextView { | ||||
|  | ||||
| 		public TextViewSelect (IntPtr javaReference, JniHandleOwnership transfer) | ||||
| 			: base(javaReference, transfer) | ||||
| 		{ | ||||
| 			Initialize(); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		public TextViewSelect(Context context): base(context, null, Android.Resource.Attribute.TextViewStyle) { | ||||
| 			Initialize(); | ||||
| 		} | ||||
| 		 | ||||
| 		public TextViewSelect(Context context, IAttributeSet attrs): base(context, attrs, Android.Resource.Attribute.TextViewStyle) { | ||||
| 			Initialize(); | ||||
| 		} | ||||
|  | ||||
| 		void Initialize () | ||||
| 		{ | ||||
| 			Focusable = true; | ||||
| 			FocusableInTouchMode = true; | ||||
| 		} | ||||
| 		 | ||||
| 		public TextViewSelect(Context context, IAttributeSet attrs, int defStyle): base(context, attrs, defStyle) { | ||||
|  | ||||
| 			Initialize (); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 		protected override IMovementMethod DefaultMovementMethod | ||||
| 		{ | ||||
| 			get | ||||
| 			{ | ||||
| 				return ArrowKeyMovementMethod.Instance; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		protected override bool DefaultEditable | ||||
| 		{ | ||||
| 			get | ||||
| 			{ | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		public override void SetText(ICharSequence text, BufferType type) { | ||||
| 			base.SetText (text, BufferType.Editable); | ||||
|  | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										70
									
								
								src/keepass2android-app/views/TextWithHelp.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/keepass2android-app/views/TextWithHelp.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| using Android.App; | ||||
| using Android.Content; | ||||
| using Android.Content.Res; | ||||
| using Android.OS; | ||||
| using Android.Runtime; | ||||
| using Android.Util; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using keepass2android; | ||||
|  | ||||
| namespace keepass2android.views | ||||
| { | ||||
| 	public class TextWithHelp : RelativeLayout | ||||
| 	{ | ||||
| 		private Kp2aShortHelpView _kp2AShortHelpView; | ||||
|  | ||||
| 		public TextWithHelp(Context context, IAttributeSet attrs) : | ||||
| 			base(context, attrs) | ||||
| 		{ | ||||
| 			Initialize(attrs); | ||||
| 		} | ||||
|  | ||||
| 		public TextWithHelp(Context context, string text, string helpText) : | ||||
| 			base(context, null) | ||||
| 		{ | ||||
| 			Initialize(text, helpText); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		public TextWithHelp(Context context, IAttributeSet attrs, int defStyle) : | ||||
| 			base(context, attrs, defStyle) | ||||
| 		{ | ||||
| 			Initialize(attrs); | ||||
| 		} | ||||
|  | ||||
| 		private void Initialize(IAttributeSet attrs) | ||||
| 		{ | ||||
|  | ||||
| 			TypedArray a = Context.ObtainStyledAttributes(attrs, Resource.Styleable.TextWithHelp); | ||||
|  | ||||
| 			string helpText = a.GetString(Resource.Styleable.TextWithHelp_help_text); | ||||
|  | ||||
| 			const string xmlns = "http://schemas.android.com/apk/res/android"; | ||||
| 			string text = Context.GetString(attrs.GetAttributeResourceValue(xmlns, "text", Resource.String.ellipsis)); | ||||
| 			Initialize(text, helpText); | ||||
| 		} | ||||
|  | ||||
| 		private void Initialize(string text, string helpText) | ||||
| 		{ | ||||
| 			LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService); | ||||
| 			inflater.Inflate(Resource.Layout.text_with_help, this); | ||||
|  | ||||
| 			_kp2AShortHelpView = ((Kp2aShortHelpView)FindViewById(Resource.Id.help)); | ||||
| 			_kp2AShortHelpView.HelpText = helpText; | ||||
|  | ||||
| 			((TextView)FindViewById(Resource.Id.text)).Text = text; | ||||
| 		} | ||||
|  | ||||
| 		public string HelpText | ||||
| 		{ | ||||
| 			get { return _kp2AShortHelpView.HelpText; } | ||||
| 			set { _kp2AShortHelpView.HelpText = value; } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll