diff --git a/apps/remix-ide/src/app/tabs/locales/en/git.json b/apps/remix-ide/src/app/tabs/locales/en/git.json index eb0a88b257..c5f4fa6a09 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/git.json +++ b/apps/remix-ide/src/app/tabs/locales/en/git.json @@ -15,5 +15,6 @@ "git.refresh": "refresh", "git.unstageall": "unstage all", "git.stageall": "stage all", - "git.noremote": "this repo has no remotes" + "git.noremote": "this repo has no remotes", + "git.init": "Initialize repository" } \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/fileSystem-api.ts b/libs/remix-api/src/lib/plugins/fileSystem-api.ts new file mode 100644 index 0000000000..04d0a2a0af --- /dev/null +++ b/libs/remix-api/src/lib/plugins/fileSystem-api.ts @@ -0,0 +1,10 @@ +import { commitChange } from "@remix-ui/git"; +import { IFileSystem } from "@remixproject/plugin-api" + +// Extended interface with 'diff' method +export interface IExtendedFileSystem extends IFileSystem { + methods: IFileSystem['methods'] & { + /** Compare the differences between two files */ + diff(change: commitChange): Promise + }; +} \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/filedecorator-api.ts b/libs/remix-api/src/lib/plugins/filedecorator-api.ts new file mode 100644 index 0000000000..a787489002 --- /dev/null +++ b/libs/remix-api/src/lib/plugins/filedecorator-api.ts @@ -0,0 +1,11 @@ +import { fileDecoration } from '@remix-ui/file-decorators' +import { StatusEvents } from '@remixproject/plugin-utils' + +export interface IFileDecoratorApi { + events: { + } & StatusEvents + methods: { + clearFileDecorators(path?: string): void + setFileDecorators(decorators: fileDecoration[]): void + } +} diff --git a/libs/remix-api/src/lib/remix-api.ts b/libs/remix-api/src/lib/remix-api.ts index aebd73be26..8469d9e057 100644 --- a/libs/remix-api/src/lib/remix-api.ts +++ b/libs/remix-api/src/lib/remix-api.ts @@ -2,6 +2,8 @@ import { IGitApi } from "@remix-ui/git" import { IRemixApi } from "@remixproject/plugin-api" import { StatusEvents } from "@remixproject/plugin-utils" import { IConfigApi } from "./plugins/config-api" +import { IFileDecoratorApi } from "./plugins/filedecorator-api" +import { IExtendedFileSystem } from "./plugins/fileSystem-api" import { INotificationApi } from "./plugins/notification-api" import { ISettings } from "./plugins/settings-api" @@ -10,6 +12,8 @@ export interface ICustomRemixApi extends IRemixApi { config: IConfigApi notification: INotificationApi settings: ISettings + fileDecorator: IFileDecoratorApi + fileManager: IExtendedFileSystem } export declare type CustomRemixApi = Readonly \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/gitui.tsx b/libs/remix-ui/git/src/components/gitui.tsx index 8140707171..0539266d8d 100644 --- a/libs/remix-ui/git/src/components/gitui.tsx +++ b/libs/remix-ui/git/src/components/gitui.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useReducer, useState } from 'react' -import { add, addall, checkout, checkoutfile, clone, commit, createBranch, remoteBranches, repositories, rm, getCommitChanges, diff, resolveRef, getBranchCommits, setUpstreamRemote, loadGitHubUserFromToken, getBranches, getRemotes, remoteCommits, saveGitHubCredentials, getGitHubCredentialsFromLocalStorage, fetch, pull, push, setDefaultRemote, addRemote, removeRemote, sendToGitLog, clearGitLog, getBranchDifferences, getFileStatusMatrix } from '../lib/gitactions' +import { add, addall, checkout, checkoutfile, clone, commit, createBranch, remoteBranches, repositories, rm, getCommitChanges, diff, resolveRef, getBranchCommits, setUpstreamRemote, loadGitHubUserFromToken, getBranches, getRemotes, remoteCommits, saveGitHubCredentials, getGitHubCredentialsFromLocalStorage, fetch, pull, push, setDefaultRemote, addRemote, removeRemote, sendToGitLog, clearGitLog, getBranchDifferences, getFileStatusMatrix, init } from '../lib/gitactions' import { loadFiles, setCallBacks } from '../lib/listeners' import { openDiff, openFile, saveToken, setModifiedDecorator, setPlugin, setUntrackedDecorator, statusChanged } from '../lib/pluginActions' import { gitActionsContext, pluginActionsContext } from '../state/context' @@ -30,12 +30,15 @@ import { BranchHeader } from './branchHeader' import { SourceControl } from './panels/sourcontrol' import { GitHubCredentials } from './panels/githubcredentials' import { Setup } from './panels/setup' +import { Init } from './panels/init' +import { CustomRemixApi } from "@remix-api"; +import { Plugin } from "@remixproject/engine"; export const gitPluginContext = React.createContext(defaultGitState) export const loaderContext = React.createContext(defaultLoaderState) interface IGitUi { - plugin: ViewPlugin + plugin: Plugin } export const GitUI = (props: IGitUi) => { @@ -44,6 +47,7 @@ export const GitUI = (props: IGitUi) => { const [loaderState, loaderDispatch] = useReducer(loaderReducer, defaultLoaderState) const [activePanel, setActivePanel] = useState("0") const [setup, setSetup] = useState(false) + const [needsInit, setNeedsInit] = useState(true) useEffect(() => { setCallBacks(plugin, gitDispatch, loaderDispatch) @@ -54,7 +58,7 @@ export const GitUI = (props: IGitUi) => { useEffect(() => { async function checkconfig() { - + const username = await plugin.call('settings', 'get', 'settings/github-user-name') const email = await plugin.call('settings', 'get', 'settings/github-email') const token = await plugin.call('settings', 'get', 'settings/gist-access-token') @@ -62,7 +66,7 @@ export const GitUI = (props: IGitUi) => { setSetup(!(username && email)) } checkconfig() - },[gitState.gitHubAccessToken, gitState.gitHubUser, gitState.userEmails]) + }, [gitState.gitHubAccessToken, gitState.gitHubUser, gitState.userEmails]) useEffect(() => { @@ -90,8 +94,10 @@ export const GitUI = (props: IGitUi) => { updatestate() }) + setNeedsInit(!(gitState.currentBranch && gitState.currentBranch.name !== '')) + }, [gitState.gitHubUser, gitState.currentBranch, gitState.remotes, gitState.gitHubAccessToken]) - + const gitActionsProviderValue = { commit, @@ -121,7 +127,8 @@ export const GitUI = (props: IGitUi) => { removeRemote, sendToGitLog, clearGitLog, - getFileStatusMatrix + getFileStatusMatrix, + init } const pluginActionsProviderValue = { @@ -139,70 +146,72 @@ export const GitUI = (props: IGitUi) => { - + - {setup? : null} - - - - - <> - - - - -
- - - <> - - - -
- - - <> - - - -
- - - <> - - -
- - - <> - - - -
- - - <> - - -
- - - <> - -
- - -
-
- - - <> - - - - -
- + {setup && !needsInit ? : null} + {needsInit ? : null} + {!setup && !needsInit ? + + + + + <> + + + + +
+ + + <> + + + +
+ + + <> + + + +
+ + + <> + + +
+ + + <> + + + +
+ + + <> + + +
+ + + <> + +
+ + +
+
+ + + <> + + + + +
+ : null}
diff --git a/libs/remix-ui/git/src/components/panels/init.tsx b/libs/remix-ui/git/src/components/panels/init.tsx new file mode 100644 index 0000000000..070acc9669 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/init.tsx @@ -0,0 +1,29 @@ +import { CustomTooltip } from '@remix-ui/helper'; +import { pull } from 'lodash'; +import React, { useContext } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { gitActionsContext } from '../../state/context'; +import GitUIButton from '../buttons/gituibutton'; + +export const Init = () => { + + const actions = React.useContext(gitActionsContext) + + const init = async () => { + actions.init() + } + + return ( + <> +
+
+ +
+
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/lib/gitactions.ts b/libs/remix-ui/git/src/lib/gitactions.ts index f38487d293..f685b94281 100644 --- a/libs/remix-ui/git/src/lib/gitactions.ts +++ b/libs/remix-ui/git/src/lib/gitactions.ts @@ -45,6 +45,13 @@ export const setPlugin = (p: Plugin, dispatcher: React.Dispatch { + console.log('gitInit') + await plugin.call('dgitApi', "init"); + await gitlog(); + await getBranches(); +} + export const getBranches = async () => { console.log('getBranches') const branches = await plugin.call('dgitApi', "branches") @@ -110,25 +117,17 @@ export const gitlog = async () => { export const showCurrentBranch = async () => { try { const branch = await currentBranch(); - const currentcommitoid = await getCommitFromRef("HEAD"); + console.log('branch :>>', branch) - if (typeof branch === "undefined" || branch.name === "") { + dispatch(setCanCommit((branch && branch.name !== ""))); + dispatch(setCurrentBranch(branch)); - branch.name = `HEAD detached at ${currentcommitoid}`; - //canCommit = false; - dispatch(setCanCommit(false)); - } else { - //canCommit = true; - dispatch(setCanCommit(true)); - dispatch(setCurrentBranch(branch)); - } } catch (e) { // show empty branch } } export const currentBranch = async () => { - // eslint-disable-next-line no-useless-catch try { const branch: branch = (await plugin.call('dgitApi', "currentbranch")) || { @@ -525,14 +524,14 @@ export const remoteCommits = async (url: string, branch: string, length: number) export const saveGitHubCredentials = async (credentials: { username: string, email: string, token: string }) => { console.log('saveGitHubCredentials', credentials) try { - const storedEmail = await plugin.call('config', 'getAppParameter','settings/github-email') - const storedUsername = await plugin.call('config', 'getAppParameter','settings/github-user-name') - const storedToken = await plugin.call('config', 'getAppParameter','settings/gist-access-token') - - if(storedUsername !== credentials.username) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', credentials.username) - if(storedEmail !== credentials.email) await plugin.call('config', 'setAppParameter', 'settings/github-email', credentials.email) - if(storedToken !== credentials.token) await plugin.call('config', 'setAppParameter', 'settings/gist-access-token', credentials.token) - + const storedEmail = await plugin.call('config', 'getAppParameter', 'settings/github-email') + const storedUsername = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') + const storedToken = await plugin.call('config', 'getAppParameter', 'settings/gist-access-token') + + if (storedUsername !== credentials.username) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', credentials.username) + if (storedEmail !== credentials.email) await plugin.call('config', 'setAppParameter', 'settings/github-email', credentials.email) + if (storedToken !== credentials.token) await plugin.call('config', 'setAppParameter', 'settings/gist-access-token', credentials.token) + } catch (e) { console.log(e) } @@ -570,17 +569,17 @@ export const loadGitHubUserFromToken = async () => { if (data && data.emails && data.user && data.user.login) { console.log('SET USER"', data) const primaryEmail = data.emails.find(email => email.primary) - + const storedEmail = await plugin.call('config', 'getAppParameter', 'settings/github-email') if (primaryEmail && storedEmail !== primaryEmail.email) await plugin.call('config', 'setAppParameter', 'settings/github-email', primaryEmail.email) const storedUsername = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') - if(data.user && data.user.login && (storedUsername !== data.user.login)) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', data.user.login) - + if (data.user && data.user.login && (storedUsername !== data.user.login)) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', data.user.login) + dispatch(setGitHubUser(data.user)) dispatch(setRateLimit(data.ratelimit)) dispatch(setScopes(data.scopes)) dispatch(setUserEmails(data.emails)) - + } } else { const credentials = await getGitHubCredentialsFromLocalStorage() diff --git a/libs/remix-ui/git/src/lib/listeners.ts b/libs/remix-ui/git/src/lib/listeners.ts index c0cf410309..2d8428b218 100644 --- a/libs/remix-ui/git/src/lib/listeners.ts +++ b/libs/remix-ui/git/src/lib/listeners.ts @@ -6,6 +6,7 @@ import { Plugin } from "@remixproject/engine"; import { getBranches, getFileStatusMatrix, loadGitHubUserFromToken, getRemotes, gitlog, setPlugin } from "./gitactions"; import { Profile } from "@remixproject/plugin-utils"; import { CustomRemixApi } from "@remix-api"; +import { statusChanged } from "./pluginActions"; let plugin: Plugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch, loadFileQueue: AsyncDebouncedQueue let callBackEnabled: boolean = false @@ -103,7 +104,9 @@ export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch { - + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) }) plugin.on('dgitApi', 'add', async () => { loadFileQueue.enqueue(async () => { @@ -200,7 +203,14 @@ const syncFromWorkspace = async (callback: Function, isLocalhost = false) => { export const loadFiles = async (filepaths: string[] = null) => { try { - await getFileStatusMatrix(filepaths); + const branch = await plugin.call('dgitApi', "currentbranch") + console.log('load files', branch) + if(branch) { + await getFileStatusMatrix(filepaths); + }else{ + await plugin.call('fileDecorator', 'clearFileDecorators') + statusChanged(0) + } } catch (e) { // TODO: handle error console.error(e); diff --git a/libs/remix-ui/git/src/lib/pluginActions.ts b/libs/remix-ui/git/src/lib/pluginActions.ts index 0832d924fc..a76194fbb5 100644 --- a/libs/remix-ui/git/src/lib/pluginActions.ts +++ b/libs/remix-ui/git/src/lib/pluginActions.ts @@ -1,13 +1,14 @@ -import { ViewPlugin } from "@remixproject/engine-web" + import { commitChange, fileStatusResult, gitActionDispatch, gitState } from "../types" import { fileDecoration, fileDecorationType } from "@remix-ui/file-decorators" import { removeSlash } from "../utils" -import path from "path" -import { getFilesByStatus, getFilesWithNotModifiedStatus } from "./fileHelpers" +import { getFilesByStatus } from "./fileHelpers" +import { CustomRemixApi } from "@remix-api"; +import { Plugin } from "@remixproject/engine"; -let plugin: ViewPlugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch +let plugin: Plugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch -export const setPlugin = (p: ViewPlugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch) => { +export const setPlugin = (p: Plugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch) => { plugin = p gitDispatch = gitDispatcher loaderDispatch = loaderDispatcher diff --git a/libs/remix-ui/git/src/state/context.tsx b/libs/remix-ui/git/src/state/context.tsx index 519119b517..a1629fb0c3 100644 --- a/libs/remix-ui/git/src/state/context.tsx +++ b/libs/remix-ui/git/src/state/context.tsx @@ -31,6 +31,7 @@ export interface gitActions { sendToGitLog: (message: gitLog) => Promise clearGitLog: () => Promise getFileStatusMatrix(filespaths:[]): Promise + init(): Promise } export const gitActionsContext = React.createContext(null)