clear cache and open file on iOS

This commit is contained in:
Kyle Spearrin 2017-07-13 10:51:45 -04:00
parent fe5cc1f8f3
commit 352c8ee867
10 changed files with 134 additions and 13 deletions

View file

@ -77,7 +77,8 @@ namespace Bit.Android
Resolver.Resolve<IGoogleAnalyticsService>(), Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(), Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>())); Resolver.Resolve<IAppSettingsService>(),
Resolver.Resolve<IDeviceActionService>()));
MessagingCenter.Subscribe<Xamarin.Forms.Application>( MessagingCenter.Subscribe<Xamarin.Forms.Application>(
Xamarin.Forms.Application.Current, "DismissKeyboard", (sender) => Xamarin.Forms.Application.Current, "DismissKeyboard", (sender) =>

View file

@ -80,5 +80,39 @@ namespace Bit.Android.Services
var activities = pm.QueryIntentActivities(intent, global::Android.Content.PM.PackageInfoFlags.MatchDefaultOnly); var activities = pm.QueryIntentActivities(intent, global::Android.Content.PM.PackageInfoFlags.MatchDefaultOnly);
return (activities?.Count ?? 0) > 0; return (activities?.Count ?? 0) > 0;
} }
public void ClearCache()
{
try
{
DeleteDir(CrossCurrentActivity.Current.Activity.CacheDir);
}
catch(Exception) { }
}
private bool DeleteDir(Java.IO.File dir)
{
if(dir != null && dir.IsDirectory)
{
var children = dir.List();
for(int i = 0; i < children.Length; i++)
{
var success = DeleteDir(new Java.IO.File(dir, children[i]));
if(!success)
{
return false;
}
}
return dir.Delete();
}
else if(dir != null && dir.IsFile)
{
return dir.Delete();
}
else
{
return false;
}
}
} }
} }

View file

@ -5,5 +5,6 @@
void CopyToClipboard(string text); void CopyToClipboard(string text);
bool OpenFile(byte[] fileData, string id, string fileName); bool OpenFile(byte[] fileData, string id, string fileName);
bool CanOpenFile(string fileName); bool CanOpenFile(string fileName);
void ClearCache();
} }
} }

View file

@ -32,6 +32,7 @@ namespace Bit.App
private readonly ILocalizeService _localizeService; private readonly ILocalizeService _localizeService;
private readonly IAppInfoService _appInfoService; private readonly IAppInfoService _appInfoService;
private readonly IAppSettingsService _appSettingsService; private readonly IAppSettingsService _appSettingsService;
private readonly IDeviceActionService _deviceActionService;
public App( public App(
string uri, string uri,
@ -45,7 +46,8 @@ namespace Bit.App
IGoogleAnalyticsService googleAnalyticsService, IGoogleAnalyticsService googleAnalyticsService,
ILocalizeService localizeService, ILocalizeService localizeService,
IAppInfoService appInfoService, IAppInfoService appInfoService,
IAppSettingsService appSettingsService) IAppSettingsService appSettingsService,
IDeviceActionService deviceActionService)
{ {
_uri = uri; _uri = uri;
_databaseService = databaseService; _databaseService = databaseService;
@ -59,6 +61,7 @@ namespace Bit.App
_localizeService = localizeService; _localizeService = localizeService;
_appInfoService = appInfoService; _appInfoService = appInfoService;
_appSettingsService = appSettingsService; _appSettingsService = appSettingsService;
_deviceActionService = deviceActionService;
SetCulture(); SetCulture();
SetStyles(); SetStyles();
@ -110,6 +113,7 @@ namespace Bit.App
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false); await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
} }
await Task.Run(() => _deviceActionService.ClearCache()).ConfigureAwait(false);
Debug.WriteLine("OnStart"); Debug.WriteLine("OnStart");
} }

View file

@ -17,7 +17,6 @@ namespace Bit.App.Controls
Detail = new Label Detail = new Label
{ {
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)), FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
LineBreakMode = LineBreakMode.TailTruncation,
Style = (Style)Application.Current.Resources["text-muted"], Style = (Style)Application.Current.Resources["text-muted"],
HorizontalOptions = LayoutOptions.End, HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center VerticalOptions = LayoutOptions.Center

View file

@ -8,6 +8,7 @@ using Xamarin.Forms;
using XLabs.Ioc; using XLabs.Ioc;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Utilities; using Bit.App.Utilities;
using System.Collections.Generic;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {
@ -38,6 +39,7 @@ namespace Bit.App.Pages
public LabeledValueCell UriCell { get; set; } public LabeledValueCell UriCell { get; set; }
public LabeledValueCell NotesCell { get; set; } public LabeledValueCell NotesCell { get; set; }
private EditLoginToolBarItem EditItem { get; set; } private EditLoginToolBarItem EditItem { get; set; }
public List<AttachmentViewCell> AttachmentCells { get; set; }
private void Init() private void Init()
{ {
@ -108,7 +110,7 @@ namespace Bit.App.Pages
Intent = TableIntent.Settings, Intent = TableIntent.Settings,
EnableScrolling = true, EnableScrolling = true,
HasUnevenRows = true, HasUnevenRows = true,
EnableSelection = false, EnableSelection = true,
Root = new TableRoot Root = new TableRoot
{ {
LoginInformationSection, LoginInformationSection,
@ -185,6 +187,7 @@ namespace Bit.App.Pages
Table.Root.Add(NotesSection); Table.Root.Add(NotesSection);
} }
CleanupAttachmentCells();
if(!Model.ShowAttachments && Table.Root.Contains(AttachmentsSection)) if(!Model.ShowAttachments && Table.Root.Contains(AttachmentsSection))
{ {
Table.Root.Remove(AttachmentsSection); Table.Root.Remove(AttachmentsSection);
@ -192,12 +195,16 @@ namespace Bit.App.Pages
else if(Model.ShowAttachments && !Table.Root.Contains(AttachmentsSection)) else if(Model.ShowAttachments && !Table.Root.Contains(AttachmentsSection))
{ {
AttachmentsSection = new TableSection(AppResources.Attachments); AttachmentsSection = new TableSection(AppResources.Attachments);
AttachmentCells = new List<AttachmentViewCell>();
foreach(var attachment in Model.Attachments) foreach(var attachment in Model.Attachments)
{ {
AttachmentsSection.Add(new AttachmentViewCell(attachment, async () => var attachmentCell = new AttachmentViewCell(attachment, async () =>
{ {
await OpenAttachmentAsync(attachment); await OpenAttachmentAsync(attachment);
})); });
AttachmentCells.Add(attachmentCell);
AttachmentsSection.Add(attachmentCell);
attachmentCell.InitEvents();
} }
Table.Root.Add(AttachmentsSection); Table.Root.Add(AttachmentsSection);
} }
@ -209,6 +216,18 @@ namespace Bit.App.Pages
{ {
NotesCell.Tapped -= NotesCell_Tapped; NotesCell.Tapped -= NotesCell_Tapped;
EditItem.Dispose(); EditItem.Dispose();
CleanupAttachmentCells();
}
private void CleanupAttachmentCells()
{
if(AttachmentCells != null)
{
foreach(var cell in AttachmentCells)
{
cell.Dispose();
}
}
} }
private async Task OpenAttachmentAsync(VaultViewLoginPageModel.Attachment attachment) private async Task OpenAttachmentAsync(VaultViewLoginPageModel.Attachment attachment)
@ -274,7 +293,7 @@ namespace Bit.App.Pages
} }
} }
public class AttachmentViewCell : LabeledRightDetailCell public class AttachmentViewCell : LabeledRightDetailCell, IDisposable
{ {
private readonly Action _tapped; private readonly Action _tapped;
@ -285,9 +304,18 @@ namespace Bit.App.Pages
Detail.Text = attachment.SizeName; Detail.Text = attachment.SizeName;
Icon.Source = "download"; Icon.Source = "download";
BackgroundColor = Color.White; BackgroundColor = Color.White;
}
public void InitEvents()
{
Tapped += AttachmentViewCell_Tapped; Tapped += AttachmentViewCell_Tapped;
} }
public void Dispose()
{
Tapped -= AttachmentViewCell_Tapped;
}
private void AttachmentViewCell_Tapped(object sender, EventArgs e) private void AttachmentViewCell_Tapped(object sender, EventArgs e)
{ {
_tapped?.Invoke(); _tapped?.Invoke();

View file

@ -20,9 +20,9 @@ namespace Bit.App
private void Init() private void Init()
{ {
//BaseAddress = new Uri("http://169.254.80.80:4000"); // Desktop from VS Android Emulator //BaseAddress = new Uri("http://169.254.80.80:4000"); // Desktop from VS Android Emulator
BaseAddress = new Uri("http://192.168.1.4:4000"); // Desktop //BaseAddress = new Uri("http://192.168.1.3:4000"); // Desktop
//BaseAddress = new Uri("https://preview-api.bitwarden.com"); // Preview //BaseAddress = new Uri("https://preview-api.bitwarden.com"); // Preview
// BaseAddress = new Uri("https://api.bitwarden.com"); // Production BaseAddress = new Uri("https://api.bitwarden.com"); // Production
DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
} }
} }

View file

@ -20,9 +20,9 @@ namespace Bit.App
private void Init() private void Init()
{ {
//BaseAddress = new Uri("http://169.254.80.80:33656"); // Desktop from VS Android Emulator //BaseAddress = new Uri("http://169.254.80.80:33656"); // Desktop from VS Android Emulator
BaseAddress = new Uri("http://192.168.1.4:33656"); // Desktop //BaseAddress = new Uri("http://192.168.1.3:33656"); // Desktop
//BaseAddress = new Uri("https://identity-api.bitwarden.com"); // Preview //BaseAddress = new Uri("https://identity-api.bitwarden.com"); // Preview
//BaseAddress = new Uri("https://identity.bitwarden.com"); // Production BaseAddress = new Uri("https://identity.bitwarden.com"); // Production
DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
} }
} }

View file

@ -69,7 +69,8 @@ namespace Bit.iOS
Resolver.Resolve<IGoogleAnalyticsService>(), Resolver.Resolve<IGoogleAnalyticsService>(),
Resolver.Resolve<ILocalizeService>(), Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IAppInfoService>(),
Resolver.Resolve<IAppSettingsService>())); Resolver.Resolve<IAppSettingsService>(),
Resolver.Resolve<IDeviceActionService>()));
// Appearance stuff // Appearance stuff

View file

@ -1,6 +1,8 @@
using System; using System;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using UIKit; using UIKit;
using Foundation;
using System.IO;
namespace Bit.iOS.Services namespace Bit.iOS.Services
{ {
@ -14,12 +16,63 @@ namespace Bit.iOS.Services
public bool OpenFile(byte[] fileData, string id, string fileName) public bool OpenFile(byte[] fileData, string id, string fileName)
{ {
return true; var filePath = Path.Combine(GetTempPath(), fileName);
File.WriteAllBytes(filePath, fileData);
var url = NSUrl.FromFilename(filePath);
var viewer = UIDocumentInteractionController.FromUrl(url);
var controller = GetVisibleViewController();
return viewer.PresentOpenInMenu(controller.View.Frame, controller.View, true);
} }
public bool CanOpenFile(string fileName) public bool CanOpenFile(string fileName)
{ {
// Not sure of a way to check this ahead of time on iOS
return true; return true;
} }
public void ClearCache()
{
var url = new NSUrl(GetTempPath());
NSError error;
var tmpFiles = NSFileManager.DefaultManager.GetDirectoryContent(url, null,
NSDirectoryEnumerationOptions.SkipsHiddenFiles, out error);
if(error == null && tmpFiles.Length > 0)
{
foreach(var item in tmpFiles)
{
NSError itemError;
NSFileManager.DefaultManager.Remove(item, out itemError);
}
}
}
private UIViewController GetVisibleViewController(UIViewController controller = null)
{
controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;
if(controller.PresentedViewController == null)
{
return controller;
}
if(controller.PresentedViewController is UINavigationController)
{
return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
}
if(controller.PresentedViewController is UITabBarController)
{
return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
}
return GetVisibleViewController(controller.PresentedViewController);
}
// ref: //https://developer.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system/
public string GetTempPath()
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var tmp = Path.Combine(documents, "..", "tmp");
return tmp;
}
} }
} }