Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create new window when dragging tab outside the app #465

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
38 changes: 35 additions & 3 deletions src/Notepads/Core/NotepadsCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Microsoft.AppCenter.Analytics;
using Notepads.Core.SessionDataModels;

public class NotepadsCore : INotepadsCore
{
Expand Down Expand Up @@ -798,15 +799,46 @@ private async void Sets_SetDraggedOutside(object sender, SetDraggedOutsideEventA
{
if (Sets.Items?.Count > 1 && e.Set.Content is ITextEditor textEditor)
{
// Only allow untitled empty document to be dragged outside for now
if (!textEditor.IsModified && textEditor.EditingFile == null)
if (textEditor.FileModificationState != FileModificationState.RenamedMovedOrDeleted)
{
DeleteTextEditor(textEditor);
soumyamahunt marked this conversation as resolved.
Show resolved Hide resolved
await NotepadsProtocolService.LaunchProtocolAsync(NotepadsOperationProtocol.OpenNewInstance);
var message = new ValueSet();
message.Add("EditorData", JsonConvert.SerializeObject(await BuildTextEditorSessionData(textEditor), Formatting.Indented));
message.Add("LastSavedText", (textEditor.IsModified || textEditor.FileModificationState == FileModificationState.Modified) && textEditor.EditingFile != null ? textEditor.LastSavedSnapshot.Content : null);
message.Add("PendingText", textEditor.IsModified ? textEditor.GetText() : null);
soumyamahunt marked this conversation as resolved.
Show resolved Hide resolved
await NotepadsProtocolService.LaunchProtocolAsync(NotepadsOperationProtocol.OpenNewInstance, message);
}
else
{
NotificationCenter.Instance.PostNotification(_resourceLoader.GetString("TextEditor_FileRenamedMovedOrDeletedIndicator_ToolTip"), 3500);
}
}
}

private async Task<TextEditorSessionDataV1> BuildTextEditorSessionData(ITextEditor textEditor)
{
TextEditorSessionDataV1 textEditorData = new TextEditorSessionDataV1
{
Id = textEditor.Id,
};

if (textEditor.EditingFile != null)
{
// Add the opened file to FutureAccessList so we can access it next launch
var futureAccessToken = textEditor.Id.ToString("N");
await FileSystemUtility.TryAddOrReplaceTokenInFutureAccessList(futureAccessToken, textEditor.EditingFile);
textEditorData.EditingFileFutureAccessToken = futureAccessToken;
textEditorData.EditingFileName = textEditor.EditingFileName;
textEditorData.EditingFilePath = textEditor.EditingFilePath;
}

textEditorData.PendingBackupFilePath = null;
textEditorData.LastSavedBackupFilePath = null;
textEditorData.StateMetaData = textEditor.GetTextEditorStateMetaData();

return textEditorData;
}

#endregion
}
}
9 changes: 7 additions & 2 deletions src/Notepads/Services/NotepadsProtocolService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AppCenter.Analytics;
using Windows.ApplicationModel;
using Windows.Foundation.Collections;
using Windows.System;

public enum NotepadsOperationProtocol
{
Expand Down Expand Up @@ -53,7 +56,7 @@ public static NotepadsOperationProtocol GetOperationProtocol(Uri uri, out string
return NotepadsOperationProtocol.Unrecognized;
}

public static async Task<bool> LaunchProtocolAsync(NotepadsOperationProtocol operation)
public static async Task<bool> LaunchProtocolAsync(NotepadsOperationProtocol operation, ValueSet message = null)
{
try
{
Expand All @@ -64,7 +67,9 @@ public static async Task<bool> LaunchProtocolAsync(NotepadsOperationProtocol ope
else if (operation == NotepadsOperationProtocol.OpenNewInstance)
{
var uriToLaunch = $"notepads://{NewInstanceProtocolStr}";
return await Windows.System.Launcher.LaunchUriAsync(new Uri(uriToLaunch.ToLower()));
var launcherOptions = new LauncherOptions();
launcherOptions.TargetApplicationPackageFamilyName = Package.Current.Id.FamilyName;
return await Launcher.LaunchUriAsync(new Uri(uriToLaunch.ToLower()), launcherOptions, message);
}
else
{
Expand Down
43 changes: 43 additions & 0 deletions src/Notepads/Views/NotepadsMainPage.IO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Notepads.Controls.TextEditor;
using Notepads.Services;
using Notepads.Utilities;
using Notepads.Models;
using Notepads.Core.SessionDataModels;

public sealed partial class NotepadsMainPage
{
Expand Down Expand Up @@ -210,5 +212,46 @@ private static bool HaveNonemptyTextEditor(ITextEditor[] textEditors)
}
return false;
}

private async Task<ITextEditor> RecoverTextEditorAsync(TextEditorSessionDataV1 editorSessionData, string lastSavedText, string pendingText)
soumyamahunt marked this conversation as resolved.
Show resolved Hide resolved
{
StorageFile editingFile = null;

if (editorSessionData.EditingFileFutureAccessToken != null)
{
editingFile = await FileSystemUtility.GetFileFromFutureAccessList(editorSessionData.EditingFileFutureAccessToken);
}

ITextEditor textEditor;

if (editingFile == null && lastSavedText == null && pendingText == null)
{
textEditor = null;
}
else if (editingFile != null && lastSavedText == null && pendingText == null) // File without pending changes
{
var encoding = EncodingUtility.GetEncodingByName(editorSessionData.StateMetaData.LastSavedEncoding);
textEditor = await _notepadsCore.CreateTextEditor(editorSessionData.Id, editingFile, encoding: encoding, ignoreFileSizeLimit: true);
textEditor.ResetEditorState(editorSessionData.StateMetaData);
}
else // File with pending changes
{
var textFile = new TextFile(lastSavedText != null ? lastSavedText : string.Empty,
EncodingUtility.GetEncodingByName(editorSessionData.StateMetaData.LastSavedEncoding),
LineEndingUtility.GetLineEndingByName(editorSessionData.StateMetaData.LastSavedLineEnding),
editorSessionData.StateMetaData.DateModifiedFileTime);

textEditor = _notepadsCore.CreateTextEditor(
editorSessionData.Id,
textFile,
editingFile,
editorSessionData.StateMetaData.FileNamePlaceholder,
editorSessionData.StateMetaData.IsModified);

textEditor.ResetEditorState(editorSessionData.StateMetaData, pendingText);
}

return textEditor;
}
}
}
21 changes: 19 additions & 2 deletions src/Notepads/Views/NotepadsMainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
using Windows.UI.Xaml.Navigation;
using Microsoft.AppCenter.Analytics;
using Windows.Graphics.Printing;
using Windows.Foundation.Collections;
using Notepads.Core.SessionDataModels;
using Newtonsoft.Json;

public sealed partial class NotepadsMainPage : Page
{
Expand All @@ -34,6 +37,7 @@ public sealed partial class NotepadsMainPage : Page
private string _appLaunchCmdDir;
private string _appLaunchCmdArgs;
private Uri _appLaunchUri;
private ValueSet _appLaunchEditorData;

private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();

Expand Down Expand Up @@ -190,6 +194,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
break;
case ProtocolActivatedEventArgs protocol:
_appLaunchUri = protocol.Uri;
_appLaunchEditorData = protocol.Data;
break;
}
}
Expand Down Expand Up @@ -231,9 +236,21 @@ private async void Sets_Loaded(object sender, RoutedEventArgs e)
else if (_appLaunchUri != null)
{
var operation = NotepadsProtocolService.GetOperationProtocol(_appLaunchUri, out var context);
if (operation == NotepadsOperationProtocol.OpenNewInstance || operation == NotepadsOperationProtocol.Unrecognized)
if (operation == NotepadsOperationProtocol.OpenNewInstance)
{
// Do nothing
try
{
var textEditor = await RecoverTextEditorAsync(JsonConvert.DeserializeObject<TextEditorSessionDataV1>((string)_appLaunchEditorData["EditorData"]),
(string)_appLaunchEditorData["LastSavedText"],
(string)_appLaunchEditorData["PendingText"]);
NotepadsCore.OpenTextEditor(textEditor);
loadedCount++;
}
catch (Exception)
{
// Do nothing
}
_appLaunchEditorData = null;
}
_appLaunchUri = null;
}
Expand Down