sync conflicts and menu layout changes, some code cleanup

This commit is contained in:
SunboX 2017-06-28 20:59:00 +02:00
Родитель e58064e29d
Коммит c6d787d88a
14 изменённых файлов: 379 добавлений и 334 удалений

Просмотреть файл

@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
# Blend for Visual Studio 15
VisualStudioVersion = 15.0.26430.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NextcloudApp", "NextcloudApp\NextcloudApp.csproj", "{99EFB7EA-88A3-4FCF-9289-22734215B5CF}"
@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NextcloudClientPortable", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism.Unity.Windows", "Prism\Source\Windows10\Prism.Unity.Windows\Prism.Unity.Windows.csproj", "{B4060AD6-7A34-479C-B5EB-4C542A681F42}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism", "Prism\Source\Prism\Prism.csproj", "{E9D9A366-83B7-4036-89A1-5A09C84081C2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism", "Prism\Source\Prism\Prism.csproj", "{E9D9A366-83B7-4036-89A1-5A09C84081C2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism.Windows", "Prism\Source\Windows10\Prism.Windows\Prism.Windows.csproj", "{3B7C3599-A336-4DB2-8678-710E3B36203B}"
EndProject

Просмотреть файл

@ -1,7 +1,4 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.UI.Xaml.Data;
@ -19,7 +16,7 @@ namespace NextcloudApp.Converter
throw new NotImplementedException();
}
public class AsyncTask : INotifyPropertyChanged
public class AsyncTask
{
public AsyncTask(object value)
{
@ -27,16 +24,13 @@ namespace NextcloudApp.Converter
LoadValue(value);
}
private async Task LoadValue(object value)
private async void LoadValue(object value)
{
string accessListKey = value.ToString();
StorageFolder tempFolder =
await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(accessListKey);
var accessListKey = value.ToString();
var tempFolder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(accessListKey);
AsyncValue = tempFolder.Path;
}
public event PropertyChangedEventHandler PropertyChanged;
public string AsyncValue { get; set; }
}
}

Просмотреть файл

@ -310,6 +310,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SampleData\SyncConflictSampleData.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="SampleData\SyncInfoDetail.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="SampleData\SyncInfoDetailSampleData.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="ShareTarget.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -424,7 +436,6 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="SampleData\" />
<Folder Include="Strings\bg-BG\" />
<Folder Include="Strings\ru\" />
</ItemGroup>

Просмотреть файл

@ -0,0 +1 @@
<Models:SyncConflict xmlns:Models="using:NextcloudApp.Models"/>

Просмотреть файл

@ -0,0 +1 @@
<RuntimeBinder:RuntimeBinderException xmlns:RuntimeBinder="using:Microsoft.CSharp.RuntimeBinder" HelpLink="Class aenean cras" Source="Curae duis aliquam"/>

Просмотреть файл

@ -0,0 +1 @@
<Models:SyncInfoDetail xmlns:Models="using:NextcloudApp.Models" ConflictType="RemoteDelLocalChange" ConflictSolution="PreferRemote" Error="Accumsan curae" ETag="Aenean cras maecenas" FilePath="Mauris praesent nullam class aliquam" FsiId="51" Id="46" Path="Nam curabitur phasellus"/>

Просмотреть файл

@ -1,7 +1,8 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:NextcloudApp">
xmlns:text="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:animation="using:Windows.UI.Xaml.Media.Animation">
<Style x:Key="SplitViewMenuButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
@ -22,11 +23,17 @@
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ActiveMarker" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ActiveMarker" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="(Grid.Background)">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListLowBrush}" />
</ObjectAnimationUsingKeyFrames>
@ -37,6 +44,9 @@
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ActiveMarker" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
@ -52,15 +62,23 @@
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ActiveMarker" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="ActiveMarker"
Background="{ThemeResource SystemControlHighlightAccentBrush}"
Width="6"
HorizontalAlignment="Left"/>
<ContentPresenter
x:Name="ContentPresenter"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"

Просмотреть файл

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NextcloudApp.Utils
namespace NextcloudApp.Utils
{
public interface IRevertState
{

Просмотреть файл

@ -1,30 +1,30 @@
namespace NextcloudApp.Utils
{
using Models;
using NextcloudClient.Types;
using SQLite.Net;
using SQLite.Net.Platform.WinRT;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Storage;
using System;
using NextcloudClient.Types;
using SQLite.Net;
using SQLite.Net.Platform.WinRT;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Storage;
using System;
using NextcloudApp.Models;
namespace NextcloudApp.Utils
{
internal static class SyncDbUtils
{
private static string dbPath = string.Empty;
private static Object fsiLock = new Object();
private static string _dbPath = string.Empty;
private static readonly object FsiLock = new object();
private static string DbPath
{
get
{
if (string.IsNullOrEmpty(dbPath))
if (string.IsNullOrEmpty(_dbPath))
{
dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "SyncStorage.sqlite");
_dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "SyncStorage.sqlite");
}
return dbPath;
return _dbPath;
}
}
@ -64,8 +64,7 @@
// Create a new connection
using (var db = DbConnection)
{
models = (from p in db.Table<FolderSyncInfo>()
select p).ToList();
models = (from p in db.Table<FolderSyncInfo>() select p).ToList();
}
return models;
@ -75,22 +74,17 @@
{
using (var db = DbConnection)
{
IEnumerable<SyncInfoDetail> sidList = (from detail in db.Table<SyncInfoDetail>()
where detail.Error != null
select detail);
IEnumerable<SyncInfoDetail> sidList = from detail in db.Table<SyncInfoDetail>() where detail.Error != null select detail;
return sidList.ToList();
}
}
public static FolderSyncInfo GetFolderSyncInfoByPath(string Path)
public static FolderSyncInfo GetFolderSyncInfoByPath(string path)
{
// Create a new connection
using (var db = DbConnection)
{
FolderSyncInfo m = (from fsi in db.Table<FolderSyncInfo>()
where fsi.Path == Path
select fsi).FirstOrDefault();
return m;
return (from fsi in db.Table<FolderSyncInfo>() where fsi.Path == path select fsi).FirstOrDefault();
}
}
@ -100,68 +94,53 @@
using (var db = DbConnection)
{
return (from sid in db.Table<SyncInfoDetail>()
where sid.FsiId == folderSyncInfo.Id
&& (sid.ConflictType != ConflictType.None
|| sid.Error != null)
where sid.FsiId == folderSyncInfo.Id
&& (sid.ConflictType != ConflictType.None
|| sid.Error != null)
select sid).Count();
}
}
public static FolderSyncInfo GetFolderSyncInfoBySubPath(string Path)
public static FolderSyncInfo GetFolderSyncInfoBySubPath(string path)
{
// Create a new connection
using (var db = DbConnection)
{
IEnumerable<FolderSyncInfo> infos = from fsi in db.Table<FolderSyncInfo>()
select fsi;
foreach(var info in infos)
{
int index = Path.IndexOf(info.Path);
if(index == 0 && Path.Substring(info.Path.Length-1, 1).Equals("/"))
{
return info;
}
}
return null;
var infos = from fsi in db.Table<FolderSyncInfo>()
select fsi;
return (from info in infos let index = path.IndexOf(info.Path, StringComparison.Ordinal) where index == 0 && path.Substring(info.Path.Length - 1, 1).Equals("/") select info).FirstOrDefault();
}
}
internal static void UnlockFolderSyncInfo(FolderSyncInfo folderSyncInfo)
{
lock(fsiLock)
lock (FsiLock)
{
using (var db = DbConnection)
{
FolderSyncInfo m = (from fsi in db.Table<FolderSyncInfo>()
where fsi.Id == folderSyncInfo.Id
select fsi).FirstOrDefault();
var m = (from fsi in db.Table<FolderSyncInfo>() where fsi.Id == folderSyncInfo.Id select fsi).FirstOrDefault();
if (m == null || !m.Active)
{
return;
}
else
{
m.Active = false;
db.Update(m);
return;
}
m.Active = false;
db.Update(m);
}
}
}
internal static bool LockFolderSyncInfo(FolderSyncInfo folderSyncInfo)
{
lock (fsiLock)
lock (FsiLock)
{
using (var db = DbConnection)
{
FolderSyncInfo m = (from fsi in db.Table<FolderSyncInfo>()
where fsi.Id == folderSyncInfo.Id
select fsi).FirstOrDefault();
if(m == null || m.Active)
var m = (from fsi in db.Table<FolderSyncInfo>() where fsi.Id == folderSyncInfo.Id select fsi).FirstOrDefault();
if (m == null || m.Active)
{
return false;
} else
}
else
{
m.Active = true;
db.Update(m);
@ -175,8 +154,7 @@
{
using (var db = DbConnection)
{
IEnumerable<FolderSyncInfo> list = (from fsi in db.Table<FolderSyncInfo>()
where fsi.Active select fsi);
IEnumerable<FolderSyncInfo> list = from fsi in db.Table<FolderSyncInfo>() where fsi.Active select fsi;
return list.ToList();
}
}
@ -204,16 +182,14 @@
// Create a new connection
string fullPath = info.Path;
if(!info.IsDirectory)
if (!info.IsDirectory)
{
fullPath = info.Path + "/" + info.Name;
}
using (var db = DbConnection)
{
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>()
where detail.Path == fullPath && detail.FsiId == fsi.Id
select detail).FirstOrDefault();
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>() where detail.Path == fullPath && detail.FsiId == fsi.Id select detail).FirstOrDefault();
return sid;
}
}
@ -230,9 +206,7 @@
using (var db = DbConnection)
{
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>()
where detail.Path == fullPath
select detail).FirstOrDefault();
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>() where detail.Path == fullPath select detail).FirstOrDefault();
return sid;
}
}
@ -242,9 +216,7 @@
// Create a new connection
using (var db = DbConnection)
{
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>()
where detail.FilePath == file.Path && detail.FsiId == fsi.Id
select detail).FirstOrDefault();
SyncInfoDetail sid = (from detail in db.Table<SyncInfoDetail>() where detail.FilePath == file.Path && detail.FsiId == fsi.Id select detail).FirstOrDefault();
return sid;
}
}
@ -253,9 +225,7 @@
{
using (var db = DbConnection)
{
IEnumerable<SyncInfoDetail> sidList = (from detail in db.Table<SyncInfoDetail>()
where detail.FsiId == fsi.Id
select detail);
IEnumerable<SyncInfoDetail> sidList = from detail in db.Table<SyncInfoDetail>() where detail.FsiId == fsi.Id select detail;
return sidList.ToList();
}
}
@ -264,9 +234,7 @@
{
using (var db = DbConnection)
{
IEnumerable<SyncInfoDetail> sidList = (from detail in db.Table<SyncInfoDetail>()
where detail.ConflictType != ConflictType.None
select detail);
IEnumerable<SyncInfoDetail> sidList = from detail in db.Table<SyncInfoDetail>() where detail.ConflictType != ConflictType.None select detail;
return sidList.ToList();
}
}
@ -279,7 +247,8 @@
{
// Including subpaths
db.Execute("DELETE FROM SyncInfoDetail WHERE Path LIKE '?%' AND FsiID = ?", sid.Path, sid.FsiId);
} else
}
else
{
db.Delete(sid);
}
@ -293,7 +262,7 @@
if (sid.Id == 0)
{
// New
db.Insert(sid);
db.Insert(sid);
}
else
{
@ -332,7 +301,7 @@
SyncDate = DateTime.Now
};
db.Insert(syncHistory);
db.Insert(syncHistory);
}
}
@ -350,7 +319,7 @@
{
// Only first 500 entries
IEnumerable<SyncHistory> historyList = (from detail in db.Table<SyncHistory>()
select detail).Take(500);
select detail).Take(500);
return historyList.OrderByDescending(x => x.SyncDate).ToList();
}
}

Просмотреть файл

@ -4,35 +4,56 @@ using System.Windows.Input;
using NextcloudApp.Models;
using NextcloudApp.Services;
using NextcloudApp.Utils;
using Prism.Windows.Navigation;
using Prism.Windows.AppModel;
using Windows.UI.Xaml.Controls;
using Windows.UI.Notifications;
using System.Linq;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
namespace NextcloudApp.ViewModels
{
public class SyncStatusPageViewModel : ViewModel
{
private readonly INavigationService _navigationService;
private readonly IResourceLoader _resourceLoader;
private readonly DialogService _dialogService;
public ObservableCollection<SyncHistory> SyncHistoryList { get; private set; }
public ObservableCollection<SyncInfoDetail> ConflictList { get; private set; }
public ObservableCollection<SyncInfoDetail> ErrorList { get; private set; }
public ObservableCollection<FolderSyncInfo> FolderSyncList { get; private set; }
public ICommand FixConflictByLocalCommand { get; private set; }
public ICommand FixConflictByRemoteCommand { get; private set; }
public ICommand FixConflictByKeepAsIsCommand { get; private set; }
public ICommand ClearSyncHistoryCommand { get; private set; }
public SyncStatusPageViewModel(INavigationService navigationService, IResourceLoader resourceLoader, DialogService dialogService)
public ObservableCollection<SyncHistory> SyncHistoryList { get; }
public ObservableCollection<SyncInfoDetail> ConflictList { get; }
public ObservableCollection<SyncInfoDetail> ErrorList { get; }
public ObservableCollection<FolderSyncInfo> FolderSyncList { get; }
public ICommand FixConflictByLocalCommand { get; }
public ICommand FixConflictByRemoteCommand { get; }
public ICommand FixConflictByKeepAsIsCommand { get; }
public ICommand ClearSyncHistoryCommand { get; }
public SyncStatusPageViewModel()
{
if (DesignMode.DesignModeEnabled)
{
ConflictList = new ObservableCollection<SyncInfoDetail>
{
new SyncInfoDetail
{
ConflictSolution = ConflictSolution.None,
ConflictType = ConflictType.BothNew,
Path = "/foo/bar/"
},
new SyncInfoDetail
{
ConflictSolution = ConflictSolution.None,
ConflictType = ConflictType.BothChanged,
Path = "/foo/bar/"
}
};
}
}
public SyncStatusPageViewModel(IResourceLoader resourceLoader, DialogService dialogService)
{
ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SyncAction);
ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SyncConflictAction);
_navigationService = navigationService;
_resourceLoader = resourceLoader;
_dialogService = dialogService;
@ -46,22 +67,21 @@ namespace NextcloudApp.ViewModels
ErrorList = new ObservableCollection<SyncInfoDetail>();
FolderSyncList = new ObservableCollection<FolderSyncInfo>();
List<SyncHistory> history = SyncDbUtils.GetSyncHistory();
var history = SyncDbUtils.GetSyncHistory();
history.ForEach(x => SyncHistoryList.Add(x));
List<SyncInfoDetail> conflicts = SyncDbUtils.GetConflicts();
var conflicts = SyncDbUtils.GetConflicts();
conflicts.ForEach(x => ConflictList.Add(x));
List<SyncInfoDetail> errors = SyncDbUtils.GetErrors();
var errors = SyncDbUtils.GetErrors();
errors.ForEach(x => ErrorList.Add(x));
List<FolderSyncInfo> fsis = SyncDbUtils.GetAllFolderSyncInfos();
var fsis = SyncDbUtils.GetAllFolderSyncInfos();
fsis.ForEach(x => FolderSyncList.Add(x));
}
private void FixConflictByLocal(object parameter)
{
ListView listView = parameter as ListView;
var listView = parameter as ListView;
if (listView == null)
{
@ -82,7 +102,7 @@ namespace NextcloudApp.ViewModels
private void FixConflictByRemote(object parameter)
{
ListView listView = parameter as ListView;
var listView = parameter as ListView;
if (listView == null)
{
@ -103,7 +123,7 @@ namespace NextcloudApp.ViewModels
private async void FixConflictByKeepAsIs(object parameter)
{
ListView listView = parameter as ListView;
var listView = parameter as ListView;
if (listView == null)
{
@ -111,7 +131,7 @@ namespace NextcloudApp.ViewModels
}
var selectedList = new List<SyncInfoDetail>();
bool usageHint = false;
var usageHint = false;
foreach (SyncInfoDetail detail in listView.SelectedItems)
{
if (detail.ConflictType == ConflictType.BothChanged ||
@ -127,32 +147,34 @@ namespace NextcloudApp.ViewModels
}
selectedList.ForEach(x => ConflictList.Remove(x));
if(usageHint)
if (!usageHint)
{
var dialog = new ContentDialog
{
Title = _resourceLoader.GetString("SyncKeepAsIsHintTitle"),
Content = new TextBlock
{
Text = _resourceLoader.GetString("SyncKeepAsIsHintDesc"),
TextWrapping = TextWrapping.WrapWholeWords,
Margin = new Thickness(0, 20, 0, 0)
},
PrimaryButtonText = _resourceLoader.GetString("OK")
};
await _dialogService.ShowAsync(dialog);
return;
}
var dialog = new ContentDialog
{
Title = _resourceLoader.GetString("SyncKeepAsIsHintTitle"),
Content = new TextBlock
{
Text = _resourceLoader.GetString("SyncKeepAsIsHintDesc"),
TextWrapping = TextWrapping.WrapWholeWords,
Margin = new Thickness(0, 20, 0, 0)
},
PrimaryButtonText = _resourceLoader.GetString("OK")
};
await _dialogService.ShowAsync(dialog);
}
private bool CanExecuteFixConflict()
{
return ConflictList?.Count() > 0;
return ConflictList?.Count > 0;
}
private void ClearSyncHistory(object parameter)
{
SyncDbUtils.DeleteSyncHistory();
SyncHistoryList.Clear();
// ReSharper disable once ExplicitCallerInfoArgument
RaisePropertyChanged(nameof(SyncHistoryList));
}
}

Просмотреть файл

@ -15,7 +15,7 @@
NavigationCacheMode="Enabled">
<Page.Resources>
<CollectionViewSource
<CollectionViewSource
x:Key="GroupedFilesAndFolders"
Source="{Binding Directory.GroupedFilesAndFolders}"
IsSourceGrouped="{Binding Settings.ShowFileAndFolderGroupingHeader}" />
@ -242,18 +242,19 @@
<Button
Grid.Column="2"
Grid.Row="0"
Grid.RowSpan="2"
Style="{StaticResource FavoriteButtonStyle}"
Command="{Binding DataContext.ToggleFavoriteCommand, ElementName=Page, Mode=OneTime}"
CommandParameter="{Binding}">
<FontIcon
Glyph="{Binding Converter={StaticResource FavoriteToIconConverter}}"
Margin="10,0,10,0"
FontFamily="Segoe MDL2 Assets"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="{StaticResource SystemControlHighlightAccentBrush}"/>
Glyph="{Binding Converter={StaticResource FavoriteToIconConverter}}"
Margin="10,0,10,0"
FontFamily="Segoe MDL2 Assets"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="{StaticResource SystemControlHighlightAccentBrush}"/>
</Button>
<interactivity:Interaction.Behaviors>

Просмотреть файл

@ -1,6 +1,4 @@
using NextcloudApp.Controls;
namespace NextcloudApp.Views
namespace NextcloudApp.Views
{
public sealed partial class DirectoryListPage
{

Просмотреть файл

@ -1,18 +1,17 @@
<UserControl x:Class="NextcloudApp.Views.MenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:NextcloudApp.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
xmlns:viewModels="using:NextcloudApp.ViewModels"
xmlns:models="using:NextcloudApp.Models"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<UserControl
x:Class="NextcloudApp.Views.MenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
xmlns:models="using:NextcloudApp.Models"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate x:Key="MenuItemTemplate" x:DataType="models:MenuItem">
<Grid>
<Button
<Button
AutomationProperties.Name="{Binding DisplayName}"
Command="{Binding Command}"
Style="{StaticResource SplitViewMenuButtonStyle}"
@ -29,117 +28,120 @@
</DataTemplate>
</UserControl.Resources>
<Grid Background="{ThemeResource SystemControlBackgroundBaseLowBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MenuStates">
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1280" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="menuItemsControl.Margin" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Medium">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="800" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="Narrow" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="1" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="12,60,12,12" Height="52">
<ScrollViewer Background="{ThemeResource SystemControlBackgroundBaseLowBrush}" Padding="0,48,12,0">
<Grid Margin="0,12,0,0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MenuStates">
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1280" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="menuItemsControl.Margin" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Medium">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="800" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="Narrow" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Height="52" Margin="12,0,12,24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Ellipse
Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="4"
Height="52"
Width="52"
Margin="0,0,8,0"
Visibility="{Binding UserAvatarUrl, Converter={StaticResource NullToVisibilityConverter}}">
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding UserAvatarUrl}"/>
</Ellipse.Fill>
</Ellipse>
<Grid
Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="4"
Height="52"
Width="52"
Margin="0,0,8,0"
Visibility="{Binding UserAvatarUrl, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=true}">
<Ellipse Fill="{ThemeResource SystemControlHighlightAccentBrush}" />
<Ellipse
Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="4"
Height="52"
Width="52"
Margin="0,0,8,0"
Visibility="{Binding UserAvatarUrl, Converter={StaticResource NullToVisibilityConverter}}">
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding UserAvatarUrl}"/>
</Ellipse.Fill>
</Ellipse>
<Grid
Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="4"
Height="52"
Width="52"
Margin="0,0,8,0"
Visibility="{Binding UserAvatarUrl, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=true}">
<Ellipse Fill="{ThemeResource SystemControlHighlightAccentBrush}" />
<TextBlock
Text="{Binding User.DisplayName, Converter={StaticResource FirstCharFromStringConverter}}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="30"
LineHeight="47"/>
</Grid>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding User.DisplayName}"
FontSize="12"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Text="{Binding User.DisplayName, Converter={StaticResource FirstCharFromStringConverter}}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="30"
LineHeight="47"/>
Grid.Row="1"
Grid.Column="1"
Text="{Binding User.EMail}"
FontSize="8"
Foreground="{ThemeResource SystemControlDisabledBaseLowBrush}"
TextTrimming="CharacterEllipsis"/>
<ProgressBar
Grid.Row="2"
Grid.Column="1"
Minimum="0"
Value="{Binding User.Quota.Used}"
Maximum="{Binding User.Quota.Total}"/>
<TextBlock
Grid.Row="3"
Grid.Column="1"
Text="{Binding QuotaUsedOfTotalString}"
FontSize="12"
TextTrimming="CharacterEllipsis"/>
</Grid>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding User.DisplayName}"
FontSize="12"
TextTrimming="CharacterEllipsis"/>
<TextBlock
<ItemsControl
Grid.Row="1"
Grid.Column="1"
Text="{Binding User.EMail}"
FontSize="8"
Foreground="{ThemeResource SystemControlDisabledBaseLowBrush}"
TextTrimming="CharacterEllipsis"/>
<ProgressBar
IsTabStop="False"
ItemTemplate="{StaticResource MenuItemTemplate}"
ItemsSource="{Binding Commands}"/>
<Border
Grid.Row="2"
Grid.Column="1"
Minimum="0"
Value="{Binding User.Quota.Used}"
Maximum="{Binding User.Quota.Total}"/>
<TextBlock
BorderThickness="1"
Height="1"
Margin="12"
BorderBrush="{ThemeResource SystemControlDisabledBaseLowBrush}"
Name="Separator"
x:FieldModifier="public" />
<ItemsControl
Grid.Row="3"
Grid.Column="1"
Text="{Binding QuotaUsedOfTotalString}"
FontSize="12"
TextTrimming="CharacterEllipsis"/>
Margin="0,0,0,6"
IsTabStop="False"
ItemTemplate="{StaticResource MenuItemTemplate}"
ItemsSource="{Binding ExtraCommands}" />
</Grid>
<ItemsControl
Grid.Row="1"
IsTabStop="False"
ItemTemplate="{StaticResource MenuItemTemplate}"
ItemsSource="{Binding Commands}" />
<Border
Grid.Row="2"
BorderThickness="1"
Margin="12,0,12,0"
BorderBrush="{ThemeResource SystemControlBackgroundBaseMediumBrush}"
Name="Separator"/>
<ItemsControl
Grid.Row="3"
Margin="0"
IsTabStop="False"
ItemTemplate="{StaticResource MenuItemTemplate}"
ItemsSource="{Binding ExtraCommands}" />
</Grid>
</ScrollViewer>
</UserControl>

Просмотреть файл

@ -4,9 +4,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
xmlns:viewModels="using:NextcloudApp.ViewModels"
x:Class="NextcloudApp.Views.SyncStatusPage"
mc:Ignorable="d"
prismMvvm:ViewModelLocator.AutoWireViewModel="True">
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
d:DataContext="{d:DesignInstance viewModels:SyncStatusPageViewModel, d:IsDesignTimeCreatable=True}">
<Grid Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}">
<Grid.RowDefinitions>
@ -128,13 +130,33 @@
</Grid.ColumnDefinitions>
<Grid
Grid.Row="0"
Grid.RowSpan="2"
Background="{StaticResource SystemControlHighlightAccentBrush}"
Height="40"
Width="40"
Margin="0,0,4,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
VerticalAlignment="Center"
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}}">
<FontIcon
Glyph="&#xE81C;"
FontFamily="Segoe MDL2 Assets"
FontSize="28"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Grid>
<Grid
Grid.Row="0"
Grid.RowSpan="2"
Background="DarkRed"
Height="40"
Width="40"
Margin="0,0,4,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}, ConverterParameter=true}">
<FontIcon
Glyph="&#xE81C;"
FontFamily="Segoe MDL2 Assets"
@ -145,24 +167,14 @@
</Grid>
<TextBlock
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}}"
Grid.Row="0"
Grid.Column="1"
Text="{Binding SyncDate, Converter={StaticResource DateTimeToStringConverter}}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
<TextBlock
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}, ConverterParameter=true}"
Grid.Row="0"
Grid.Column="1"
Text="{Binding SyncDate, Converter={StaticResource DateTimeToStringConverter}}"
Foreground="Red"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
<TextBlock
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}}"
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path}"
@ -170,15 +182,6 @@
Foreground="{ThemeResource SystemControlForegroundChromeDisabledLowBrush}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis"/>
<TextBlock
Visibility="{Binding ConflictType, Converter={StaticResource ConflictTypeNoneToVisibilityConverter}, ConverterParameter=true}"
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path}"
FontSize="12"
Foreground="Red"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis"/>
</Grid>
@ -202,57 +205,83 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView Name="ConflictListView" ItemsSource="{Binding ConflictList}" SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView
Name="ConflictListView"
Grid.Row="0"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
ItemsSource="{Binding ConflictList}"
SelectionMode="Multiple"
Padding="0,2,0,2"
HorizontalContentAlignment="Stretch">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="12,2,4,2"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid
Background="{StaticResource SystemControlHighlightAccentBrush}"
Height="40"
Width="40"
Margin="0,0,4,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<FontIcon
Glyph="&#xE783;"
FontFamily="Segoe MDL2 Assets"
FontSize="28"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Grid>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding ConflictType, Converter={StaticResource ConflictTypeToStringConverter}}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path}"
FontSize="12"
Foreground="{ThemeResource SystemControlForegroundChromeDisabledLowBrush}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis"/>
<Grid
Grid.Row="0"
Grid.Column="0"
Background="{StaticResource SystemControlHighlightAccentBrush}"
Height="40"
Width="40"
Margin="0,08,4,4"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<FontIcon
Glyph="&#xE783;"
FontFamily="Segoe MDL2 Assets"
FontSize="30"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="2,1,0,0"
Foreground="White" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding Path}"
Foreground="{ThemeResource SystemControlForegroundChromeDisabledLowBrush}"
FontSize="12"
VerticalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Text="{Binding ConflictType, Converter={StaticResource ConflictTypeToStringConverter}}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
TextWrapping="Wrap"
VerticalAlignment="Top"/>
<Border
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,12,0,2"
Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}"
Height="1"
HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<CommandBar Grid.Row="1" VerticalAlignment="Bottom">
<!-- Buttons for fix options -->
@ -287,7 +316,9 @@
Padding="0,0,0,2">
<ListView.HeaderTemplate>
<DataTemplate>
<Border Background="{ThemeResource SystemControlHighlightAccentBrush}">
<Border
Background="{ThemeResource SystemControlHighlightAccentBrush}"
Margin="0,0,0,2">
<TextBlock
Text="{Binding}"
TextWrapping="WrapWholeWords"
@ -314,6 +345,7 @@
</Grid.ColumnDefinitions>
<Grid
Grid.RowSpan="2"
Background="{StaticResource SystemControlHighlightAccentBrush}"
Height="40"
Width="40"
@ -323,7 +355,8 @@
<FontIcon
Glyph="&#xE783;"
FontFamily="Segoe MDL2 Assets"
FontSize="28"
FontSize="30"
Margin="2,1,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />