From 353b5670adba5eb3357f819a5ed27832098d7fdf Mon Sep 17 00:00:00 2001 From: filip mertens Date: Thu, 2 May 2024 21:54:03 +0200 Subject: [PATCH] listeners --- .../src/components/buttons/commitmessage.tsx | 3 +- libs/remix-ui/git/src/components/gitui.tsx | 6 +- .../navigation/sourcecontrolgroup.tsx | 8 +- .../git/src/components/panels/branches.tsx | 12 +- libs/remix-ui/git/src/lib/gitactions.ts | 55 +++++---- libs/remix-ui/git/src/lib/listeners.ts | 113 +++++++++++------- libs/remix-ui/git/src/state/context.tsx | 4 +- .../workspace/src/lib/actions/workspace.ts | 2 +- 8 files changed, 123 insertions(+), 80 deletions(-) diff --git a/libs/remix-ui/git/src/components/buttons/commitmessage.tsx b/libs/remix-ui/git/src/components/buttons/commitmessage.tsx index d2f275af21..0721ab5c91 100644 --- a/libs/remix-ui/git/src/components/buttons/commitmessage.tsx +++ b/libs/remix-ui/git/src/components/buttons/commitmessage.tsx @@ -33,8 +33,9 @@ export const CommitMessage = () => { const commit = async() => { if (context.staged.length === 0 && context.allchangesnotstaged.length == 0) return if (context.staged.length === 0) - await actions.addall() + await actions.addall(context.allchangesnotstaged) await actions.commit(message.value) + setMessage({ value: '' }) } const getRemote = () => { diff --git a/libs/remix-ui/git/src/components/gitui.tsx b/libs/remix-ui/git/src/components/gitui.tsx index cbbb58417d..c48c569b4e 100644 --- a/libs/remix-ui/git/src/components/gitui.tsx +++ b/libs/remix-ui/git/src/components/gitui.tsx @@ -29,6 +29,8 @@ import LogViewer from './panels/log' import { SourceControlBase } from './buttons/sourceControlBase' import { BranchHeader } from './branchHeader' import { SourceControl } from './panels/sourcontrol' +import { Settings } from './panels/settings' +import { GitHubCredentials } from './panels/githubcredentials' export const gitPluginContext = React.createContext(defaultGitState) export const loaderContext = React.createContext(defaultLoaderState) @@ -157,7 +159,7 @@ export const GitUI = (props: IGitUi) => { <> - +
@@ -177,6 +179,8 @@ export const GitUI = (props: IGitUi) => { <> +
+

diff --git a/libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx b/libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx index b5852a5337..968fb0673d 100644 --- a/libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx +++ b/libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx @@ -5,6 +5,7 @@ import React, { useContext, useEffect } from "react"; import { FormattedMessage } from "react-intl"; import { gitActionsContext, pluginActionsContext } from "../../state/context"; import { sourceControlGroup } from "../../types"; +import { gitPluginContext } from "../gitui"; interface SourceControlGroupNavigationProps { eventKey: string; @@ -17,6 +18,7 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation const { eventKey, activePanel, callback, group } = props; const actions = React.useContext(gitActionsContext) const pluginActions = React.useContext(pluginActionsContext) + const context = React.useContext(gitPluginContext) const handleClick = () => { if (!callback) return if (activePanel === eventKey) { @@ -39,11 +41,7 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation {group.name === 'Changes' ? }> - - : null} - {group.name === 'Staged' ? - }> - + : null} : null diff --git a/libs/remix-ui/git/src/components/panels/branches.tsx b/libs/remix-ui/git/src/components/panels/branches.tsx index 7419e37b5f..678ba687a9 100644 --- a/libs/remix-ui/git/src/components/panels/branches.tsx +++ b/libs/remix-ui/git/src/components/panels/branches.tsx @@ -7,7 +7,11 @@ import { gitPluginContext } from "../gitui"; import { LocalBranchDetails } from "./branches/localbranchdetails"; import { RemoteBranchDetails } from "./branches/remotebranchedetails"; -export const Branches = () => { +interface BranchesProps { + isOpen: boolean; +} + +export const Branches = ({isOpen}: BranchesProps) => { const context = React.useContext(gitPluginContext) const actions = React.useContext(gitActionsContext) const [newBranch, setNewBranch] = useState({ value: "" }); @@ -24,6 +28,12 @@ export const Branches = () => { } }; + useEffect(() => { + console.log("open branches", context.branches) + //if(context.branches && context.branches.length) return + //actions.getBranches() + },[isOpen]) + useEffect(() => { console.log("branches", context.branches) },[context.branches]) diff --git a/libs/remix-ui/git/src/lib/gitactions.ts b/libs/remix-ui/git/src/lib/gitactions.ts index 64c943a04f..28aea82577 100644 --- a/libs/remix-ui/git/src/lib/gitactions.ts +++ b/libs/remix-ui/git/src/lib/gitactions.ts @@ -2,7 +2,7 @@ import { ViewPlugin } from "@remixproject/engine-web"; import { ReadBlobResult, ReadCommitResult } from "isomorphic-git"; import React from "react"; import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog } from "../state/gitpayload"; -import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog } from '../types'; +import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog, fileStatusResult } from '../types'; import { removeSlash } from "../utils"; import { disableCallBacks, enableCallBacks } from "./listeners"; import { AlertModal, ModalTypes } from "@remix-ui/app"; @@ -229,7 +229,11 @@ export const commit = async (message: string = "") => { }, message: message, }); - plugin.call('notification', 'toast', `Commited: ${sha}`) + + sendToGitLog({ + type:'success', + message: `Commited: ${sha}` + }) } catch (err) { plugin.call('notification', 'toast', `${err}`) @@ -237,24 +241,19 @@ export const commit = async (message: string = "") => { } -export const addall = async () => { +export const addall = async (files: fileStatusResult[]) => { try { - await plugin - .call("dGitProvider", "status", { ref: "HEAD" }) - .then((status) => - Promise.all( - status.map(([filepath, , worktreeStatus]) => - worktreeStatus - ? plugin.call("dGitProvider", "add", { - filepath: removeSlash(filepath), - }) - : plugin.call("dGitProvider", "rm", { - filepath: removeSlash(filepath), - }) - ) - ) - ); - plugin.call('notification', 'toast', `Added all files to git`) + console.log('addall', files.map(f => removeSlash(f.filename))) + const filesToAdd = files.map(f => removeSlash(f.filename)) + try { + await plugin.call("dGitProvider", "add", { + filepath: filesToAdd, + }); + } catch (e) { } + sendToGitLog({ + type:'success', + message: `Added all files to git` + }) } catch (e) { plugin.call('notification', 'toast', `${e}`) @@ -269,7 +268,7 @@ export const add = async (args: string | undefined) => { filename = removeSlash(filename); stagingfiles = [filename]; } else { - await addall(); + //await addall(); return; } try { @@ -280,7 +279,10 @@ export const add = async (args: string | undefined) => { }); } catch (e) { } } - plugin.call('notification', 'toast', `Added ${filename} to git`); + sendToGitLog({ + type:'success', + message: `Added ${filename} to git` + }) } catch (e) { plugin.call('notification', 'toast', `${e}`) } @@ -302,7 +304,10 @@ export const rm = async (args: any) => { await plugin.call("dGitProvider", "rm", { filepath: removeSlash(filename), }); - plugin.call('notification', 'toast', `Removed ${filename} from git`) + sendToGitLog({ + type:'success', + message: `Removed ${filename} from git` + }) } export const checkoutfile = async (filename: string) => { @@ -364,7 +369,11 @@ export const clone = async (url: string, branch: string, depth: number, singleBr //} else { await plugin.call('dGitProvider' as any, 'clone', { url, branch, token, depth, singleBranch }, repoNameWithTimestamp); await enableCallBacks() - plugin.call('notification', 'toast', `Cloned ${url} to ${repoNameWithTimestamp}`) + + sendToGitLog({ + type:'success', + message: `Cloned ${url} to ${repoNameWithTimestamp}` + }) //} } catch (e: any) { await parseError(e) diff --git a/libs/remix-ui/git/src/lib/listeners.ts b/libs/remix-ui/git/src/lib/listeners.ts index 285df1138b..0cedc1d0ab 100644 --- a/libs/remix-ui/git/src/lib/listeners.ts +++ b/libs/remix-ui/git/src/lib/listeners.ts @@ -5,36 +5,65 @@ import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog } from ". import { gitActionDispatch } from "../types"; import { diffFiles, getBranches, getFileStatusMatrix, getGitHubUser, getRemotes, gitlog, setPlugin } from "./gitactions"; -let plugin: ViewPlugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch +let plugin: ViewPlugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch, loadFileQueue: AsyncDebouncedQueue let callBackEnabled: boolean = false let syncTimer: NodeJS.Timer = null +type AsyncCallback = () => Promise; + +class AsyncDebouncedQueue { + private queues: Map; + + constructor(private delay: number = 300) { + this.queues = new Map(); + } + + enqueue(callback: AsyncCallback, customDelay?:number): void { + if (this.queues.has(callback)) { + clearTimeout(this.queues.get(callback)!.timer); + } + + let timer = setTimeout(async () => { + await callback(); // Await the asynchronous operation + this.queues.delete(callback); + }, customDelay || this.delay); + + this.queues.set(callback, { timer, lastCall: Date.now() }); + } +} + + + export const setCallBacks = (viewPlugin: ViewPlugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch) => { plugin = viewPlugin gitDispatch = gitDispatcher loaderDispatch = loaderDispatcher + loadFileQueue = new AsyncDebouncedQueue() setPlugin(viewPlugin, gitDispatcher) plugin.on("fileManager", "fileSaved", async (file: string) => { console.log(file) - loadFiles([file]) - //await synTimerStart(); + loadFileQueue.enqueue(async () => { + loadFiles() + }) }); plugin.on('dGitProvider', 'checkout' as any, async () => { - await synTimerStart(); + //await synTimerStart(); }) plugin.on('dGitProvider', 'branch' as any, async () => { - await synTimerStart(); + //await synTimerStart(); }) plugin.on("fileManager", "fileAdded", async (e) => { - await synTimerStart(); + loadFileQueue.enqueue(async () => { + loadFiles() + }) }); plugin.on("fileManager", "fileRemoved", async (e) => { - await synTimerStart(); + //await synTimerStart(); }); plugin.on("fileManager", "currentFileChanged", async (e) => { @@ -43,53 +72,71 @@ export const setCallBacks = (viewPlugin: ViewPlugin, gitDispatcher: React.Dispat }); plugin.on("fileManager", "fileRenamed", async (oldfile, newfile) => { - await synTimerStart(); + //await synTimerStart(); }); plugin.on("filePanel", "setWorkspace", async (x: any) => { - await synTimerStart(); + loadFileQueue.enqueue(async () => { + loadFiles() + }) + loadFileQueue.enqueue(async () => { + gitlog() + }) + loadFileQueue.enqueue(async () => { + getBranches() + }) + loadFileQueue.enqueue(async () => { + getRemotes() + }) }); plugin.on("filePanel", "deleteWorkspace" as any, async (x: any) => { - await synTimerStart(); + //await synTimerStart(); }); plugin.on("filePanel", "renameWorkspace" as any, async (x: any) => { - await synTimerStart(); + //await synTimerStart(); }); plugin.on('dGitProvider', 'checkout', async () => { - await loadFiles(); + }) plugin.on('dGitProvider', 'init', async () => { - await loadFiles(); + }) plugin.on('dGitProvider', 'add', async () => { - await loadFiles(); + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) }) plugin.on('dGitProvider', 'rm', async () => { - await loadFiles(); + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) }) plugin.on('dGitProvider', 'commit', async () => { + loadFileQueue.enqueue(async () => { + gitlog() + }, 10) gitDispatch(setLog({ message: 'Committed changes...', type: 'success' })) - await loadFiles(); }) plugin.on('dGitProvider', 'branch', async () => { gitDispatch(setLog({ message: "Created Branch", type: "success" })) - await loadFiles(); }) plugin.on('dGitProvider', 'clone', async () => { gitDispatch(setLog({ message: "Cloned Repository", type: "success" })) - await loadFiles(); + loadFileQueue.enqueue(async () => { + loadFiles() + }) }) plugin.on('manager', 'pluginActivated', async (p: Plugin) => { if (p.name === 'dGitProvider') { @@ -117,7 +164,7 @@ export const getGitConfig = async () => { return config } -const syncFromWorkspace = async (isLocalhost = false) => { +const syncFromWorkspace = async (callback: Function, isLocalhost = false) => { //gitDispatch(setLoading(true)); await disableCallBacks(); if (isLocalhost) { @@ -142,35 +189,17 @@ const syncFromWorkspace = async (isLocalhost = false) => { } catch (e) { gitDispatch(setCanUseApp(false)); } - await loadFiles(); + await callback(); await enableCallBacks(); } export const loadFiles = async (filepaths: string[] = null) => { - //gitDispatch(setLoading(true)); - try { await getFileStatusMatrix(filepaths); } catch (e) { // TODO: handle error console.error(e); } - try { - await gitlog(); - } catch (e) { } - try { - await getBranches(); - } catch (e) { } - try { - await getRemotes(); - } catch (e) { } - try { - //await getStorageUsed(); - } catch (e) { } - try { - //await diffFiles(''); - } catch (e) { } - //gitDispatch(setLoading(false)); } const getStorageUsed = async () => { @@ -192,11 +221,3 @@ export const enableCallBacks = async () => { callBackEnabled = true; } -const synTimerStart = async () => { - //console.trace('synTimerStart') - if (!callBackEnabled) return - clearTimeout(syncTimer) - syncTimer = setTimeout(async () => { - await syncFromWorkspace(); - }, 1000) -} diff --git a/libs/remix-ui/git/src/state/context.tsx b/libs/remix-ui/git/src/state/context.tsx index b1bfb01ce0..b50ff4d9f3 100644 --- a/libs/remix-ui/git/src/state/context.tsx +++ b/libs/remix-ui/git/src/state/context.tsx @@ -1,6 +1,6 @@ import { ReadCommitResult } from "isomorphic-git" import React from "react" -import { branch, commitChange, gitLog, gitState, remote } from "../types" +import { branch, commitChange, fileStatusResult, gitLog, gitState, remote } from "../types" export interface gitActions { removeRemote(remote: remote): void @@ -8,7 +8,7 @@ export interface gitActions { add(path: string): Promise rm(path: string): Promise commit(message: string): Promise - addall(): Promise + addall(files: fileStatusResult[]): Promise push(remote?: string, ref?: string, remoteRef?: string, force?: boolean): Promise pull(remote?: string, ref?: string, remoteRef?: string): Promise fetch(remote?: string, ref?: string, remoteRef?: string, depth?: number, singleBranch?: boolean, relative?: boolean, quiet?: boolean): Promise diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index d91a445631..9200a38569 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -754,7 +754,7 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => { dir: addSlash(workspaceName), } const currentBranch: branch = await plugin.call('dGitProvider', 'currentbranch', { ...gitConfig }) - return currentBranch.name + return currentBranch && currentBranch.name } export const showAllBranches = async () => {