/// <summary> /// Initializes the commands and sets <see cref="CredentialTokens"/> to an empty collection. /// The ViewModel must be activated before use. /// </summary> /// <param name="accessList">A list used to look up candidates to get their underlying files.</param> /// <param name="exportService">Used to export stored files.</param> /// <param name="proxyProvider">Provider to use for accessing stored databases.</param> /// <param name="deletePrompter">Service to use for prompting user consent/understanding.</param> /// <param name="updatePrompter">Service to use for prompting user consent/understanding.</param> /// <param name="fileService">Service to use for accessing the filesystem.</param> public CachedFilesViewModel( IDatabaseAccessList accessList, IFileExportService exportService, IFileProxyProvider proxyProvider, IUserPromptingService deletePrompter, IUserPromptingService updatePrompter, IFileAccessService fileService ) : base(accessList, proxyProvider, exportService, deletePrompter, updatePrompter, fileService) { this.accessList = accessList; this.proxyProvider = proxyProvider; this.deleteAllCommand = new AsyncActionCommand( async() => { if (await this.proxyProvider.TryDeleteAllProxiesAsync() .ConfigureAwait(false) ) { ClearAllFiles(); } else { // If clearing wasn't successful we might need to add back some // files. await ResyncFiles(); } } ); }
/// <summary> /// Initializes the commands and sets <see cref="CredentialTokens"/> to an empty collection. /// The ViewModel must be activated before use. /// </summary> /// <param name="credentialProvider">Provider to use for accessing stored credentials.</param> public SavedCredentialsViewModel( ICredentialStorageProvider credentialProvider ) { this.credentialProvider = credentialProvider ?? throw new ArgumentNullException(nameof(credentialProvider)); this.deleteCredentialCommand = new AsyncTypedCommand <string>( (token) => token != null, async(token) => { if (this.allCredentials.Contains(token)) { await this.credentialProvider.DeleteAsync(token); this.allCredentials.Remove(token); } } ); this.deleteAllCommand = new AsyncActionCommand( async() => { await this.credentialProvider.ClearAsync(); this.allCredentials.Clear(); } ); this.allCredentials = new ObservableCollection <string>(); }
/// <summary> /// Initializes the design data. /// </summary> public DesignDatabaseUnlockViewModel() { CandidateFile = new MockDatabaseCandidate { FileName = "My Database.kdbx", LastModified = new DateTimeOffset(DateTime.UtcNow), Size = 12345, }; Password = "******"; UnlockCommand = new AsyncActionCommand( () => HasGoodHeader, () => Task.CompletedTask ); UseSavedCredentialsCommand = new AsyncActionCommand( () => true, () => Task.CompletedTask ); HasGoodHeader = true; ParseResult = new ReaderResult(KdbxParserCode.Success); RememberDatabase = true; }
/// <summary> /// Initializes the model from the provided struct. /// </summary> /// <param name="accessListEntry">The AccessListEntry to use as a reference.</param> public StoredFileDescriptor(AccessListEntry accessListEntry) { this.accessListEntry = accessListEntry; this.isAppOwned = false; this.forgetCommand = new AsyncActionCommand(FireForgetRequested); this.exportCommand = new ActionCommand(FireExportRequested); this.updateCommand = new AsyncActionCommand(() => IsAppOwned, FireUpdateRequested); this.openCommand = new ActionCommand(FireOpenRequested); }
public async Task ShouldExecuteAsynchronous() { bool executeCalled = false; var command = new AsyncActionCommand <int>(o => { executeCalled = true; return(Task.CompletedTask); }); await command.ExecuteAsync(); Assert.IsTrue(executeCalled); }
public DiagnosticTraceButtonViewModel(IFolderPickerService folderPicker, IEventLogger logger, IEventTracer tracer, string startTraceLabel, string stopTraceLabel) { this.isBusy = false; this.folderPicker = folderPicker ?? throw new ArgumentNullException(nameof(folderPicker)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.tracer = tracer ?? throw new ArgumentNullException(nameof(tracer)); this.traceCommand = new AsyncActionCommand(() => !this.isBusy, ToggleTrace); this.startTraceLabel = startTraceLabel; this.stopTraceLabel = stopTraceLabel; IsTracing = false; }
public async Task ShouldReceiveParameterAsynchronous() { int receivedParameter = 0; var command = new AsyncActionCommand <int>(o => { receivedParameter = o; return(Task.CompletedTask); }); int parameterValue = 5; await command.ExecuteAsync(parameterValue); Assert.AreEqual(parameterValue, receivedParameter); }
public async Task ShouldRaiseCanExecuteChangedAsynchronous() { bool canExecuteCalled = false; var command = new AsyncActionCommand(o => Task.FromResult((object)null), o => { canExecuteCalled = true; return(Task.FromResult(true)); }); await command.RefreshAsync(); Assert.IsTrue(canExecuteCalled); }
public CategoryPageViewModel( ILogger logger, IDataManager dataManager, IWindowManager windowManager, CommonViewModel commonViewModel) { _logger = Arguments.NotNull(logger, nameof(logger)); _dataManager = Arguments.NotNull(dataManager, nameof(dataManager)); CommonViewModel = Arguments.NotNull(commonViewModel, nameof(commonViewModel)); WindowManager = Arguments.NotNull(windowManager, nameof(windowManager)); AddAccountCommand = new AsyncActionCommand <object>(_logger, AddAccountEvent, ExecuteAddAccountCommandAsync); GeneratePasswordCommand = new AsyncActionCommand <object>(_logger, GeneratePasswordEvent, ExecuteGeneratePasswordCommandAsync); DeleteAccountCommand = new AsyncActionCommand <Account>(_logger, DeleteAccountEvent, ExecuteDeleteAccountCommandAsync); PaneClosingCommand = new ActionCommand <SplitViewPaneClosingEventArgs>(_logger, PaneClosingEvent, ExecutePaneClosingCommand); }
/// <summary> /// Initializes the view model. /// </summary> public MasterKeyViewModel(IFileAccessService fileService) { this.fileService = fileService ?? throw new ArgumentNullException(nameof(fileService)); this.keyfileCommand = new AsyncActionCommand( async() => { KeyFile = await fileService.PickFileForOpenAsync(); } ); this.confirmCommand = new AsyncActionCommand( () => (!String.IsNullOrEmpty(this.password) || this.keyFile != null) && this.password == this.confirmedPassword, () => HandleCredentialsAsync(this.password, this.keyFile) ); }
public async Task ShouldSetEnabledToFalseAsynchronous() { bool[] canExecute = { true }; var command = new AsyncActionCommand <int>( o => Task.CompletedTask, async o => { await Task.Yield(); return(canExecute[0]); }); await command.RefreshAsync(); Assert.IsTrue(command.Enabled); canExecute[0] = false; await command.RefreshAsync(); Assert.IsFalse(command.Enabled); }
/// <summary> /// Initializes a new instance of the class. /// </summary> /// <param name="syncContext">Synchronization context used for marshalling to the UI thread.</param> /// <param name="file">The candidate document file.</param> /// <param name="isSampleFile">Whether the file is a PassKeep sample.</param> /// <param name="futureAccessList">A database access list for persisting permission to the database.</param> /// <param name="reader">The IKdbxReader implementation used for parsing document files.</param> /// <param name="proxyProvider">Generates file proxies that the app controls.</param> /// <param name="candidateFactory">Factory used to generate new candidate files as needed.</param> /// <param name="keyChangeVmFactory">Factory used to generate the objects used to modify the master key of the database.</param> /// <param name="taskNotificationService">A service used to notify the UI of blocking operations.</param> /// <param name="identityService">The service used to verify the user's consent for saving credentials.</param> /// <param name="credentialProvider">The provider used to store/load saved credentials.</param> /// <param name="credentialViewModelFactory">A factory used to generate <see cref="ISavedCredentialsViewModel"/> instances.</param> public DatabaseUnlockViewModel( ISyncContext syncContext, IDatabaseCandidate file, bool isSampleFile, IDatabaseAccessList futureAccessList, IKdbxReader reader, IFileProxyProvider proxyProvider, IDatabaseCandidateFactory candidateFactory, IMasterKeyChangeViewModelFactory keyChangeVmFactory, ITaskNotificationService taskNotificationService, IIdentityVerificationService identityService, ICredentialStorageProvider credentialProvider, ISavedCredentialsViewModelFactory credentialViewModelFactory ) { this.syncContext = syncContext ?? throw new ArgumentNullException(nameof(syncContext)); this.futureAccessList = futureAccessList; this.kdbxReader = reader ?? throw new ArgumentNullException(nameof(reader)); this.proxyProvider = proxyProvider ?? throw new ArgumentNullException(nameof(proxyProvider)); this.candidateFactory = candidateFactory ?? throw new ArgumentNullException(nameof(candidateFactory)); this.keyChangeVmFactory = keyChangeVmFactory ?? throw new ArgumentNullException(nameof(keyChangeVmFactory)); this.taskNotificationService = taskNotificationService ?? throw new ArgumentNullException(nameof(taskNotificationService)); this.identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); this.credentialProvider = credentialProvider ?? throw new ArgumentNullException(nameof(credentialProvider)); this.credentialViewModelFactory = credentialViewModelFactory ?? throw new ArgumentNullException(nameof(credentialViewModelFactory)); SaveCredentials = false; IdentityVerifiability = UserConsentVerifierAvailability.Available; UnlockCommand = new AsyncActionCommand(CanUnlock, DoUnlockAsync); UseSavedCredentialsCommand = new AsyncActionCommand( () => UnlockCommand.CanExecute(null) && HasSavedCredentials, DoUnlockWithSavedCredentials ); IsSampleFile = isSampleFile; RememberDatabase = true; this.initialConstruction = UpdateCandidateFileAsync(file); }
public GameBoardTileViewModel( IGameplayService gameplayService, GameStateModel gameState) { _subscriptions = new CompositeDisposable(); var cachedModel = Observable.CombineLatest( this.ObserveProperty(x => x.ColIndex), this.ObserveProperty(x => x.RowIndex), gameState.GameBoard, (colIndex, rowIndex, gameBoard) => gameBoard .Tiles .FirstOrDefault(x => (x.ColIndex == colIndex) && (x.RowIndex == rowIndex))) .ToCached() .DisposeWith(_subscriptions); var modelContent = cachedModel .Select(x => x?.Content ?? Observable.Return <DominoModel>(null)) .SelectLatest(); Observable.CombineLatest( modelContent .Select(x => x?.FirstSuit), modelContent .Select(x => x?.SecondSuit), cachedModel .Select(x => x?.IsRotated), (firstSuit, secondSuit, isRotated) => (firstSuit, secondSuit, isRotated)) .Subscribe(x => { if (!(x.isRotated is null)) { if (x.isRotated.Value) { FirstSuit = x.secondSuit; SecondSuit = x.firstSuit; } else { FirstSuit = x.firstSuit; SecondSuit = x.secondSuit; } } }) .DisposeWith(_subscriptions); modelContent .Select(x => x is null) .Subscribe(x => IsEmpty = x) .DisposeWith(_subscriptions); cachedModel .Select(x => x?.IsFaceUp?.Select(y => (bool?)y) ?? Observable.Return <bool?>(null)) .SelectLatest() .Subscribe(x => IsFaceUp = x) .DisposeWith(_subscriptions); FlipCommand = new AsyncActionCommand( cancellationToken => gameplayService.FlipTileAsync(cachedModel.Value, cancellationToken), gameplayService.ObserveCanFlipTile(cachedModel)) .DisposeWith(_subscriptions); }
/// <summary> /// Passes provided parameters to the base constructor and initializes commands. /// </summary> /// <param name="resourceProvider">IResourceProvider for localizing strings.</param> /// <param name="navigationViewModel"></param> /// <param name="persistenceService"></param> /// <param name="clipboardService"></param> /// <param name="settingsService"></param> /// <param name="document"></param> /// <param name="entry"></param> /// <param name="isNew"></param> /// <param name="isReadOnly"></param> /// <param name="rng"></param> private EntryDetailsViewModel( IResourceProvider resourceProvider, IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, ISensitiveClipboardService clipboardService, IAppSettingsService settingsService, KdbxDocument document, IKeePassEntry entry, bool isNew, bool isReadOnly, IRandomNumberGenerator rng ) : base(navigationViewModel, persistenceService, document, entry, isNew, isReadOnly) { this.resourceProvider = resourceProvider; this.clipboardService = clipboardService; this.settingsService = settingsService; this.rng = rng; this.copyFieldValueCommand = new TypedCommand <IProtectedString>( str => { clipboardService.CopyCredential(str.ClearValue, ClipboardOperationType.Other); } ); this.deleteFieldCommand = new TypedCommand <IProtectedString>( str => !IsReadOnly && PersistenceService.CanSave, str => { DebugHelper.Assert(!IsReadOnly); WorkingCopy.Fields.Remove(str); } ); this.editFieldCommand = new AsyncTypedCommand <IProtectedString>( str => PersistenceService.CanSave, async str => { IsReadOnly = false; await UpdateFieldEditorViewModel(new FieldEditorViewModel(str, this.resourceProvider)); } ); this.newFieldCommand = new AsyncActionCommand( () => PersistenceService.CanSave, async() => { IsReadOnly = false; await UpdateFieldEditorViewModel(new FieldEditorViewModel(this.rng, this.resourceProvider)); } ); this.commitFieldCommand = new AsyncActionCommand( () => FieldEditorViewModel?.CommitCommand.CanExecute(WorkingCopy) ?? false, async() => { FieldEditorViewModel.CommitCommand.Execute(WorkingCopy); await UpdateFieldEditorViewModel(null); } ); PropertyChanged += (s, e) => { if (e.PropertyName == nameof(IsReadOnly)) { ((TypedCommand <IProtectedString>)DeleteFieldCommand).RaiseCanExecuteChanged(); } else if (e.PropertyName == nameof(WorkingCopy)) { OnPropertyChanged(nameof(WorkingCopyViewModel)); } }; }