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

Settings Sync #2684

Open
1208nn opened this issue May 2, 2024 · 3 comments
Open

Settings Sync #2684

1208nn opened this issue May 2, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@1208nn
Copy link

1208nn commented May 2, 2024

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.

@1208nn 1208nn added the enhancement New feature or request label May 2, 2024
@Garulf
Copy link
Member

Garulf commented May 2, 2024

Flow Launcher can be used in portable mode allowing the use of cloud drives, git, syncthing, etc.

@1208nn
Copy link
Author

1208nn commented May 3, 2024

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);
        }
    }
}

@onesounds
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants