/// <summary> /// add virtual definition as an asynchronous operation. /// </summary> /// <param name="definitions">The definitions.</param> protected async Task AddVirtualDefinitionAsync(IEnumerable <IDefinition> definitions) { if (previousDefinitions != definitions) { if (!IsBinaryConflict) { var col = definitions.OrderBy(p => SelectedModsOrder.IndexOf(p.ModName)).ToHashSet(); var priorityDefinition = modPatchCollectionService.EvalDefinitionPriority(col); if (priorityDefinition == null || priorityDefinition.Definition == null) { if (priorityDefinition == null) { priorityDefinition = DIResolver.Get <IPriorityDefinitionResult>(); priorityDefinition.PriorityType = DefinitionPriorityType.None; } if (priorityDefinition.Definition == null) { priorityDefinition.Definition = col.First(); } } var newDefinition = await modPatchCollectionService.CreatePatchDefinitionAsync(priorityDefinition.Definition, CollectionName); if (newDefinition != null) { col.Add(newDefinition); } VirtualDefinitions = col.ToObservableCollection(); if (VirtualDefinitions.Count() > 0) { // No reason to anymore not select a default definition on either side, wait a bit first to allow the UI to settle down await Task.Delay(100); LeftSelectedDefinition = null; RightSelectedDefinition = null; await Task.Delay(50); LeftSelectedDefinition = VirtualDefinitions.FirstOrDefault(p => p != newDefinition && p != priorityDefinition.Definition); RightSelectedDefinition = newDefinition; } } else { VirtualDefinitions = definitions.OrderBy(p => SelectedModsOrder.IndexOf(p.ModName)).ToHashSet(); if (VirtualDefinitions.Count() > 0) { // No reason to anymore not select a default definition on either side, wait a bit first to allow the UI to settle down await Task.Delay(100); LeftSelectedDefinition = null; RightSelectedDefinition = null; await Task.Delay(50); LeftSelectedDefinition = definitions.ElementAt(0); RightSelectedDefinition = definitions.ElementAt(1); } } } previousDefinitions = definitions; }
/// <summary> /// Called when [activated]. /// </summary> /// <param name="disposables">The disposables.</param> protected override void OnActivated(CompositeDisposable disposables) { var resolvingEnabled = this.WhenAnyValue(v => v.ResolvingConflict, v => !v); BackCommand = ReactiveCommand.Create(() => { Conflicts?.Dispose(); Conflicts = null; SelectedModsOrder = null; SelectedModCollection = null; var args = new NavigationEventArgs() { State = NavigationState.Main }; ReactiveUI.MessageBus.Current.SendMessage(args); }).DisposeWith(disposables); ResolveCommand = ReactiveCommand.Create(() => { ResolveConflictAsync(true).ConfigureAwait(true); }, resolvingEnabled).DisposeWith(disposables); IgnoreCommand = ReactiveCommand.Create(() => { ResolveConflictAsync(false).ConfigureAwait(true); }, resolvingEnabled).DisposeWith(disposables); InvalidOpenDirectoryCommand = ReactiveCommand.CreateFromTask(async() => { if (!string.IsNullOrWhiteSpace(InvalidConflictPath)) { await appAction.OpenAsync(Path.GetDirectoryName(InvalidConflictPath)); } }).DisposeWith(disposables); InvalidOpenFileCommand = ReactiveCommand.CreateFromTask(async() => { if (!string.IsNullOrWhiteSpace(InvalidConflictPath)) { await appAction.OpenAsync(InvalidConflictPath); } }).DisposeWith(disposables); this.WhenAnyValue(p => p.Conflicts).Subscribe(s => { FilterHierarchalConflictsAsync(s).ConfigureAwait(false); IgnoreConflictsRules.CollectionName = SelectedModCollection.Name; IgnoreConflictsRules.ConflictResult = s; ResetConflicts.SetParameters(s, SelectedModCollection.Name); DatabaseSearch.SetParameters(s); CustomConflicts.SetParameters(s, SelectedModCollection.Name); MergeViewer.InitParameters(); }).DisposeWith(disposables); this.WhenAnyValue(v => v.SelectedParentConflict).Subscribe(s => { IsConflictSolverAvailable = !(s?.Key == InvalidKey); EvalViewerVisibility(); }).DisposeWith(disposables); this.WhenAnyValue(v => v.SelectedConflict).Subscribe(s => { if (Conflicts?.Conflicts != null && !string.IsNullOrWhiteSpace(s?.Key) && IsConflictSolverAvailable) { PreviousConflictIndex = SelectedParentConflict.Children.ToList().IndexOf(s); var conflicts = Conflicts.Conflicts.GetByTypeAndId(s.Key).ToObservableCollection(); ModCompareSelector.SelectedModsOrder = SelectedModsOrder; ModCompareSelector.CollectionName = SelectedModCollection.Name; ModCompareSelector.IsBinaryConflict = IsBinaryConflict = conflicts?.FirstOrDefault()?.ValueType == ValueType.Binary; ModCompareSelector.Definitions = conflicts; MergeViewer.SetSidePatchMod(modPatchCollectionService.IsPatchMod(ModCompareSelector.LeftSelectedDefinition?.ModName), modPatchCollectionService.IsPatchMod(ModCompareSelector.RightSelectedDefinition?.ModName)); MergeViewer.SetText(string.Empty, string.Empty, true); MergeViewer.ExitEditMode(); EvalViewerVisibility(); IgnoreEnabled = true; } else { if (HierarchalConflicts == null || !HierarchalConflicts.Any()) { ModCompareSelector.Reset(); BinaryMergeViewer.Reset(); MergeViewer.SetText(string.Empty, string.Empty, true); } PreviousConflictIndex = null; IgnoreEnabled = false; } }).DisposeWith(disposables); this.WhenAnyValue(v => v.ModCompareSelector.IsActivated).Where(p => p).Subscribe(s => { this.WhenAnyValue(v => v.ModCompareSelector.LeftSelectedDefinition).Subscribe(s => { if (s != null && IsConflictSolverAvailable) { MergeViewer.EditingYaml = s.Type.StartsWith(Shared.Constants.LocalizationDirectory); MergeViewer.SetSidePatchMod(modPatchCollectionService.IsPatchMod(ModCompareSelector.LeftSelectedDefinition?.ModName), modPatchCollectionService.IsPatchMod(ModCompareSelector.RightSelectedDefinition?.ModName)); MergeViewer.SetText(s.Code, MergeViewer.RightSide); MergeViewer.ExitEditMode(); if (!IsBinaryConflict) { BinaryMergeViewer.EnableSelection = ResolveEnabled = ModCompareSelector.LeftSelectedDefinition != null && ModCompareSelector.RightSelectedDefinition != null && ModCompareSelector.LeftSelectedDefinition != ModCompareSelector.RightSelectedDefinition && (modPatchCollectionService.IsPatchMod(ModCompareSelector.LeftSelectedDefinition.ModName) || modPatchCollectionService.IsPatchMod(ModCompareSelector.RightSelectedDefinition.ModName)); } else { BinaryMergeViewer.Reset(false); ResolveEnabled = false; BinaryMergeViewer.EnableSelection = ModCompareSelector.LeftSelectedDefinition != null && ModCompareSelector.RightSelectedDefinition != null && ModCompareSelector.LeftSelectedDefinition != ModCompareSelector.RightSelectedDefinition; BinaryMergeViewer.SetLeft(s); } } else { BinaryMergeViewer.Reset(); ResolveEnabled = false; } }).DisposeWith(disposables); this.WhenAnyValue(v => v.ModCompareSelector.RightSelectedDefinition).Subscribe(s => { if (s != null && IsConflictSolverAvailable) { MergeViewer.EditingYaml = s.Type.StartsWith(Shared.Constants.LocalizationDirectory); MergeViewer.SetSidePatchMod(modPatchCollectionService.IsPatchMod(ModCompareSelector.LeftSelectedDefinition?.ModName), modPatchCollectionService.IsPatchMod(ModCompareSelector.RightSelectedDefinition?.ModName)); MergeViewer.SetText(MergeViewer.LeftSide, s.Code); MergeViewer.ExitEditMode(); if (!IsBinaryConflict) { BinaryMergeViewer.EnableSelection = ResolveEnabled = ModCompareSelector.LeftSelectedDefinition != null && ModCompareSelector.RightSelectedDefinition != null && ModCompareSelector.LeftSelectedDefinition != ModCompareSelector.RightSelectedDefinition && (modPatchCollectionService.IsPatchMod(ModCompareSelector.LeftSelectedDefinition.ModName) || modPatchCollectionService.IsPatchMod(ModCompareSelector.RightSelectedDefinition.ModName)); } else { BinaryMergeViewer.Reset(false); ResolveEnabled = false; BinaryMergeViewer.EnableSelection = ModCompareSelector.LeftSelectedDefinition != null && ModCompareSelector.RightSelectedDefinition != null && ModCompareSelector.LeftSelectedDefinition != ModCompareSelector.RightSelectedDefinition; BinaryMergeViewer.SetRight(s); } } else { BinaryMergeViewer.Reset(); ResolveEnabled = false; } }).DisposeWith(disposables); }).DisposeWith(disposables); this.WhenAnyValue(v => v.BinaryMergeViewer.IsActivated).Where(p => p).Subscribe(s => { Observable.Merge(BinaryMergeViewer.TakeLeftCommand.Select(s => true), BinaryMergeViewer.TakeRightCommand.Select(s => false)).Subscribe(s => { takeLeftBinary = s; ResolveEnabled = true; }).DisposeWith(disposables); }).DisposeWith(disposables); this.WhenAnyValue(p => p.MergeViewer.LeftSide).Where(p => !string.IsNullOrWhiteSpace(p)).Subscribe(s => { if (MergeViewer.LeftSidePatchMod) { var patchDefinition = ModCompareSelector.VirtualDefinitions.FirstOrDefault(p => modPatchCollectionService.IsPatchMod(p.ModName)); SyncCode(patchDefinition); } }).DisposeWith(disposables); this.WhenAnyValue(p => p.MergeViewer.RightSide).Where(p => !string.IsNullOrWhiteSpace(p)).Subscribe(s => { if (MergeViewer.RightSidePatchMod) { var patchDefinition = ModCompareSelector.VirtualDefinitions.FirstOrDefault(p => modPatchCollectionService.IsPatchMod(p.ModName)); SyncCode(patchDefinition); } }).DisposeWith(disposables); this.WhenAnyValue(v => v.IgnoreConflictsRules.IsActivated).Where(p => p).Subscribe(s => { Observable.Merge(IgnoreConflictsRules.SaveCommand, IgnoreConflictsRules.CancelCommand).Subscribe(result => { switch (result.State) { case Implementation.CommandState.Success: EditingIgnoreConflictsRules = false; FilterHierarchalConflictsAsync(Conflicts, SelectedConflict).ConfigureAwait(false); break; case Implementation.CommandState.NotExecuted: EditingIgnoreConflictsRules = false; break; default: break; } }).DisposeWith(disposables); }).DisposeWith(disposables); IgnoreRulesCommand = ReactiveCommand.Create(() => { EditingIgnoreConflictsRules = true; }).DisposeWith(disposables); InvalidCustomPatchCommand = ReactiveCommand.Create(() => { if (HoveredDefinition.AdditionalData is IDefinition definition) { CustomConflicts.SetContent(definition.File, definition.Code); } }).DisposeWith(disposables); this.WhenAnyValue(p => p.ModFilter.IsActivated).Where(p => p).Subscribe(s => { ModFilter.SetConflictResult(Conflicts, SelectedModsOrder.ToList(), SelectedModCollection.Name); this.WhenAnyValue(p => p.ModFilter.HasSavedState).Where(p => p).Subscribe(s => { FilterHierarchalConflictsAsync(Conflicts, SelectedConflict).ConfigureAwait(false); }).DisposeWith(disposables); }).DisposeWith(disposables); this.WhenAnyValue(p => p.ResetConflicts.IsActivated).Where(p => p).Subscribe(s => { ResetConflicts.ResetCommand.Subscribe(s => { if (s.State == Implementation.CommandState.Success) { FilterHierarchalConflictsAsync(Conflicts, SelectedConflict).ConfigureAwait(false); } }).DisposeWith(disposables); }).DisposeWith(disposables); this.WhenAnyValue(p => p.CustomConflicts.Saved).Where(p => p).Subscribe(s => { ResetConflicts.Refresh(); }).DisposeWith(disposables); base.OnActivated(disposables); }
/// <summary> /// add virtual definition as an asynchronous operation. /// </summary> /// <param name="definitions">The definitions.</param> /// <param name="token">The token.</param> /// <returns>A Task representing the asynchronous operation.</returns> protected async Task AddVirtualDefinitionAsync(IEnumerable <IDefinition> definitions, CancellationToken token) { addingVirtualDefinition = true; if (previousDefinitions != definitions) { if (!IsBinaryConflict) { var col = definitions.OrderBy(p => SelectedModsOrder.IndexOf(p.ModName)).ToHashSet(); var priorityDefinition = modPatchCollectionService.EvalDefinitionPriority(col); if (priorityDefinition == null || priorityDefinition.Definition == null) { if (priorityDefinition == null) { priorityDefinition = DIResolver.Get <IPriorityDefinitionResult>(); priorityDefinition.PriorityType = DefinitionPriorityType.None; } if (priorityDefinition.Definition == null) { priorityDefinition.Definition = col.First(); } } IDefinition newDefinition = null; if (priorityDefinition.PriorityType != DefinitionPriorityType.NoProvider) { newDefinition = await modPatchCollectionService.CreatePatchDefinitionAsync(priorityDefinition.Definition, CollectionName); if (newDefinition != null) { col.Add(newDefinition); } } VirtualDefinitions = col.ToObservableCollection(); var virtualDefinitions = VirtualDefinitions; if (virtualDefinitions.Any()) { // No reason to anymore not select a default definition on either side, wait a bit first to allow the UI to settle down await Task.Delay(100, token); if (!token.IsCancellationRequested) { DefinitionSelection = null; LeftSelectedDefinition = null; RightSelectedDefinition = null; } await Task.Delay(50, token); if (!token.IsCancellationRequested) { int virtualDefCount = virtualDefinitions.Count(); var left = newDefinition != null?virtualDefinitions.FirstOrDefault(p => p != newDefinition && p != priorityDefinition.Definition && !(virtualDefCount >= 4 && p.IsFromGame)) : virtualDefinitions.FirstOrDefault(p => p != priorityDefinition.Definition); if (left == null) { left = virtualDefinitions.FirstOrDefault(p => p != newDefinition && p != priorityDefinition.Definition); } var right = newDefinition ?? priorityDefinition.Definition; DefinitionSelection = new CompareSelection(left, right); LeftSelectedDefinition = left; RightSelectedDefinition = right; } } } else { VirtualDefinitions = definitions.OrderBy(p => SelectedModsOrder.IndexOf(p.ModName)).ToHashSet(); var virtualDefinitions = VirtualDefinitions; var priorityDefinition = modPatchCollectionService.EvalDefinitionPriority(virtualDefinitions); if (priorityDefinition == null || priorityDefinition.Definition == null) { if (priorityDefinition == null) { priorityDefinition = DIResolver.Get <IPriorityDefinitionResult>(); priorityDefinition.PriorityType = DefinitionPriorityType.None; } if (priorityDefinition.Definition == null) { priorityDefinition.Definition = virtualDefinitions.First(); } } if (virtualDefinitions.Any()) { // No reason to anymore not select a default definition on either side, wait a bit first to allow the UI to settle down await Task.Delay(100, token); if (!token.IsCancellationRequested) { DefinitionSelection = null; LeftSelectedDefinition = null; RightSelectedDefinition = null; } await Task.Delay(50, token); if (!token.IsCancellationRequested) { var left = virtualDefinitions.FirstOrDefault(p => p != priorityDefinition.Definition); var right = priorityDefinition.Definition; DefinitionSelection = new CompareSelection(left, right); LeftSelectedDefinition = left; RightSelectedDefinition = right; } } } } previousDefinitions = definitions; addingVirtualDefinition = false; }