Flow.Launcher
Flow.Launcher copied to clipboard
Settings Sync
Setting up sync is a good feature to use Flow between devices, which make our experience better.
If flowlaunchher has no plans to create an account system or buy a server, syncing through OneDrive, GoogleDrive, WebDav is also acceptable and a good solution. For example, tampermonkey, violentmonkey use these methods.
I think we can sync the settings folder, themes folder, and a list of plugins.
It's a ok to sync like vscode
, only a json file with the list of plugins.
Flow Launcher can be used in portable mode allowing the use of cloud drives, git, syncthing, etc.
It's true but it really costs my space and time. Sync the whole app in cloud might have some problem for too many files.
Flowlauncher was packed with runtime. Can they be deleted if I installed .net?
I think just sync a folder wasn't difficult. In C#,we can use Microsoft.Graph.
This is an example (bad code):
using Microsoft.Graph;
using Microsoft.Identity.Client;
using System;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace OneDriveAppFolderExample{
class Program{
private static GraphServiceClient graphClient;
private static string clientId = "*#*#*#*#*";
private static string[] scopes = new string[] { "Files.ReadWrite.AppFolder" };
static async Task Main(string[] args){
var authProvider = new InteractiveAuthenticationProvider(clientId, scopes);
graphClient = new GraphServiceClient(authProvider);
var appFolder = await CreateAppFolder();
await UploadFileToAppFolder(appFolder, @"UserData/settings");
//This need keep flow's working directory not change
//In file search plugin, if user use the position of the executable file as the working directory, it will not work. We need not change the working directory of the main process.
}
private static async Task<DriveItem> CreateAppFolder(){
try{
var appFolder = await graphClient.Me.Drive.Special.AppRoot
.Request()
.GetAsync();
return appFolder;
}
catch (ServiceException ex){
if (ex.StatusCode == System.Net.HttpStatusCode.NotFound){
var folderToCreate = new DriveItem{
Name = "Flow.Launcher",
Folder = new Folder()
};
var appFolder = await graphClient.Me.Drive.Special.AppRoot
.Children
.Request()
.AddAsync(folderToCreate);
return appFolder;
}
else{
throw;
}
}
}
private static async Task UploadFileToAppFolder(DriveItem appFolder, string localFilePath){
using (var fileStream = System.IO.File.OpenRead(localFilePath)){
var uploadedFile = await graphClient.Me.Drive.Items[appFolder.Id]
.ItemWithPath(System.IO.Path.GetFileName(localFilePath))
.Content
.Request()
.PutAsync<DriveItem>(fileStream);
Console.WriteLine("Uploaded file ID: " + uploadedFile.Id);
}
}
}
public class InteractiveAuthenticationProvider : IAuthenticationProvider {
private IPublicClientApplication _msalClient;
private string[] _scopes;
public InteractiveAuthenticationProvider(string clientId, string[] scopes){
_msalClient = PublicClientApplicationBuilder.Create(clientId).Build();
_scopes = scopes;
}
public async Task AuthenticateRequestAsync(HttpRequestMessage request){
var authResult = await _msalClient.AcquireTokenInteractive(_scopes).ExecuteAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
}
}
}
We want to create this feature, but we don't have anyone to work on it now. (Sadly, The simple setting backup/restore feature too.)
If you know how to write code, please make a PR.
We definitely won't be hosting this solution ourselves. It will have to be a third-party solution but everyone's got their own preferred sync platform, e.g. OneDrive, GoogleDrive or etc.
Maybe should consider allowing the UserData folder be relocated to a separate location so only that folder gets synced, and user data is also loaded from the new location.
The aText program uses two quite good solutions:
-
Sync folder → makes a daily backup to a selected folder → similarly, if this backup is updated due to aText from another machine, it loads it immediately.
-
Simple daily backup → creates a daily backup in a folder (max 100 items), from which it can be easily imported if needed. For me, this second solution would also be suitable, it doesn't have to be completely automatic, but at least such a "semi-automatic" solution would be great, I think.
The problem with that is how to handle a conflict if modified by both side?
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 60 days.\n\nAlternatively this issue can be kept open by adding one of the following labels:\nkeep-fresh