From 82967cf6a938917973e4e9d75096d03eff769b9e Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 9 Aug 2022 09:13:16 +0100 Subject: [PATCH 01/19] Stack file-explorer and dgit options --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 25975f37b4..1d37566abe 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -495,6 +495,8 @@ export function Workspace () { ] return ( + <> +
@@ -678,6 +680,11 @@ export function Workspace () {
+
+
+ DGIT +
+ ) } From e9174de49901c05a757dc7d83ea97ade7b1cab1c Mon Sep 17 00:00:00 2001 From: David Disu Date: Wed, 10 Aug 2022 14:22:54 +0100 Subject: [PATCH 02/19] branch UI --- .../workspace/src/lib/remix-ui-workspace.tsx | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 1d37566abe..5f368f9ba2 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -497,7 +497,6 @@ export function Workspace () { return ( <>
-
@@ -679,10 +678,22 @@ export function Workspace () {
-
- -
- DGIT +
+
+
+
DGIT
+
+ + + Main + + + + setup + + +
+
) From 64434abc0dcaf7c20c89da44161b246c9a5d336c Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 22 Aug 2022 09:22:46 +0100 Subject: [PATCH 03/19] fetch branches --- apps/remix-ide/src/app/files/dgitProvider.js | 16 ++-- .../helper/src/lib/remix-ui-helper.ts | 5 ++ .../workspace/src/lib/actions/payload.ts | 2 +- .../workspace/src/lib/actions/workspace.ts | 82 +++++++++++++++++-- .../workspace/src/lib/reducers/workspace.ts | 17 ++-- .../workspace/src/lib/remix-ui-workspace.tsx | 2 +- 6 files changed, 104 insertions(+), 20 deletions(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index 28f7fb2715..019caec3c7 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -9,6 +9,7 @@ import { saveAs } from 'file-saver' import http from 'isomorphic-git/http/web' +import { IndexedDBStorage } from './filesystems/indexedDB' const JSZip = require('jszip') const path = require('path') @@ -145,17 +146,16 @@ class DGitProvider extends Plugin { return status } - async currentbranch () { - const name = await git.currentBranch({ - ...await this.getGitConfig() - }) + async currentbranch (config) { + console.log('config: ', config) + const cmd = config ? config : await this.getGitConfig() + const name = await git.currentBranch(cmd) + return name } - async branches () { - const cmd = { - ...await this.getGitConfig() - } + async branches (config) { + const cmd = config ? config : await this.getGitConfig() const remotes = await this.remotes() let branches = [] branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } }) diff --git a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts index d9fd9b03b9..02a688b9a6 100644 --- a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts +++ b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts @@ -123,3 +123,8 @@ export const shortenHexData = (data) => { const len = data.length return data.slice(0, 5) + '...' + data.slice(len - 5, len) } + +export const addSlash = (file: string) => { + if (!file.startsWith('/'))file = '/' + file + return file +} diff --git a/libs/remix-ui/workspace/src/lib/actions/payload.ts b/libs/remix-ui/workspace/src/lib/actions/payload.ts index 8c3fb8fc18..e9acca3087 100644 --- a/libs/remix-ui/workspace/src/lib/actions/payload.ts +++ b/libs/remix-ui/workspace/src/lib/actions/payload.ts @@ -126,7 +126,7 @@ export const createWorkspaceRequest = (promise: Promise) => { } } -export const createWorkspaceSuccess = (workspaceName: { name: string; isGitRepo: boolean; }) => { +export const createWorkspaceSuccess = (workspaceName: { name: string; isGitRepo: boolean; branches?: { remote: any; name: string; }[], currentBranch?: string }) => { return { type: 'CREATE_WORKSPACE_SUCCESS', payload: workspaceName diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 0495875a87..f12fcd4209 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -2,12 +2,18 @@ import React from 'react' import { bufferToHex, keccakFromString } from 'ethereumjs-util' import axios, { AxiosResponse } from 'axios' import { addInputFieldSuccess, cloneRepositoryFailed, cloneRepositoryRequest, cloneRepositorySuccess, createWorkspaceError, createWorkspaceRequest, createWorkspaceSuccess, displayNotification, displayPopUp, fetchWorkspaceDirectoryError, fetchWorkspaceDirectoryRequest, fetchWorkspaceDirectorySuccess, hideNotification, setCurrentWorkspace, setDeleteWorkspace, setMode, setReadOnlyMode, setRenameWorkspace } from './payload' -import { checkSlash, checkSpecialChars } from '@remix-ui/helper' +import { addSlash, checkSlash, checkSpecialChars } from '@remix-ui/helper' import { JSONStandardInput, WorkspaceTemplate } from '../types' import { QueryParams } from '@remix-project/remix-lib' import * as templateWithContent from '@remix-project/remix-ws-templates' import { ROOT_PATH } from '../utils/constants' +// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries +import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB' + +declare global { + interface Window { remixFileSystemCallback: IndexedDBStorage; } +} const LOCALHOST = ' - connect to localhost - ' @@ -48,6 +54,25 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName) dispatch(createWorkspaceRequest(promise)) promise.then(async () => { + if (isGitRepo) { + let branches = [] + let currentBranch = null + + try { + branches = await getGitRepoBranches(`${plugin.fileProviders.workspace.workspacesPath}/${workspaceName}`) + } catch (e) { + console.error(e) + } + try { + currentBranch = await getGitRepoCurrentBranch(`${plugin.fileProviders.workspace.workspacesPath}/${workspaceName}`) + } catch (e) { + console.error(e) + } + + dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo, branches, currentBranch })) + } else { + dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) + } dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) await plugin.setWorkspace({ name: workspaceName, isLocalhost: false }) await plugin.setWorkspaces(await getWorkspaces()) @@ -263,7 +288,7 @@ export const switchToWorkspace = async (name: string) => { if (isActive) await plugin.call('manager', 'deactivatePlugin', 'remixd') await plugin.fileProviders.workspace.setWorkspace(name) await plugin.setWorkspace({ name, isLocalhost: false }) - const isGitRepo = await plugin.fileManager.isGitRepo() + const isGitRepo = await plugin.fileManager.isGitRepo(name) dispatch(setMode('browser')) dispatch(setCurrentWorkspace({ name, isGitRepo })) @@ -325,10 +350,37 @@ export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean Promise.all(Object.keys(items) .filter((item) => items[item].isDirectory) .map(async (folder) => { + console.log('folder: ', folder) const isGitRepo: boolean = await plugin.fileProviders.browser.exists('/' + folder + '/.git') - return { - name: folder.replace(workspacesPath + '/', ''), - isGitRepo + + if (isGitRepo) { + let branches = [] + let currentBranch = null + + try { + branches = await getGitRepoBranches(folder) + } catch (e) { + console.error(e) + } + try { + currentBranch = await getGitRepoCurrentBranch(folder) + } catch (e) { + console.error(e) + } + + console.log('branches: ', branches) + + return { + name: folder.replace(workspacesPath + '/', ''), + isGitRepo, + branches, + currentBranch + } + } else { + return { + name: folder.replace(workspacesPath + '/', ''), + isGitRepo + } } })).then(workspacesList => resolve(workspacesList)) }) @@ -397,3 +449,23 @@ export const getRepositoryTitle = async (url: string) => { return name + counter } + +export const getGitRepoBranches = async (workspacePath: string) => { + const gitConfig: { fs: IndexedDBStorage, dir: string } = { + fs: window.remixFileSystemCallback, + dir: addSlash(workspacePath) + } + const branches: { remote: any; name: string; }[] = await plugin.call('dGitProvider', 'branches', gitConfig) + + return branches +} + +export const getGitRepoCurrentBranch = async (workspaceName: string) => { + const gitConfig: { fs: IndexedDBStorage, dir: string } = { + fs: window.remixFileSystemCallback, + dir: addSlash(workspaceName) + } + const currentBranch: string = await plugin.call('dGitProvider', 'currentbranch', gitConfig) + + return currentBranch +} diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index af20d18fa2..ba78892d51 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -13,6 +13,11 @@ export interface BrowserState { workspaces: { name: string; isGitRepo: boolean; + branches?: { + remote: any; + name: string; + }[], + currentBranch?: string }[], files: { [x: string]: Record }, expandPath: string[] @@ -117,7 +122,7 @@ export const browserInitialState: BrowserState = { export const browserReducer = (state = browserInitialState, action: Action) => { switch (action.type) { case 'SET_CURRENT_WORKSPACE': { - const payload = action.payload as { name: string; isGitRepo: boolean; } + const payload = action.payload as { name: string; isGitRepo: boolean; branches?: { remote: any; name: string; }[], currentBranch?: string } const workspaces = state.browser.workspaces.find(({ name }) => name === payload.name) ? state.browser.workspaces : [...state.browser.workspaces, action.payload] return { @@ -131,7 +136,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => { } case 'SET_WORKSPACES': { - const payload = action.payload as { name: string; isGitRepo: boolean; }[] + const payload = action.payload as { name: string; isGitRepo: boolean; branches?: { remote: any; name: string; }[], currentBranch?: string }[] return { ...state, @@ -429,7 +434,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => { } case 'CREATE_WORKSPACE_SUCCESS': { - const payload = action.payload as { name: string; isGitRepo: boolean; } + const payload = action.payload as { name: string; isGitRepo: boolean; branches?: { remote: any; name: string; }[], currentBranch?: string } const workspaces = state.browser.workspaces.find(({ name }) => name === payload.name) ? state.browser.workspaces : [...state.browser.workspaces, action.payload] return { @@ -460,13 +465,15 @@ export const browserReducer = (state = browserInitialState, action: Action) => { case 'RENAME_WORKSPACE': { const payload = action.payload as { oldName: string, workspaceName: string } let renamedWorkspace - const workspaces = state.browser.workspaces.filter(({ name, isGitRepo }) => { + const workspaces = state.browser.workspaces.filter(({ name, isGitRepo, branches, currentBranch }) => { if (name && (name !== payload.oldName)) { return true } else { renamedWorkspace = { name: payload.workspaceName, - isGitRepo + isGitRepo, + branches, + currentBranch } return false } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 5f368f9ba2..e953fcbaea 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -679,7 +679,7 @@ export function Workspace () { -
+
DGIT
From 569b189f0a7df296541be10192aeab552179ab37 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 23 Aug 2022 12:09:26 +0100 Subject: [PATCH 04/19] List branches --- apps/remix-ide/src/app/files/dgitProvider.js | 1 - .../workspace/src/lib/actions/index.ts | 1 + .../workspace/src/lib/actions/workspace.ts | 37 ++---------------- .../workspace/src/lib/reducers/workspace.ts | 1 + .../workspace/src/lib/remix-ui-workspace.tsx | 39 ++++++++++++------- 5 files changed, 30 insertions(+), 49 deletions(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index 019caec3c7..6f8abe3025 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -147,7 +147,6 @@ class DGitProvider extends Plugin { } async currentbranch (config) { - console.log('config: ', config) const cmd = config ? config : await this.getGitConfig() const name = await git.currentBranch(cmd) diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index aa06fb7840..8c48726c98 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -53,6 +53,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. const params = queryParams.get() as UrlParametersType const workspaces = await getWorkspaces() || [] dispatch(setWorkspaces(workspaces)) + // console.log('workspaces: ', workspaces) if (params.gist) { await createWorkspaceTemplate('gist-sample', 'gist-template') plugin.setWorkspace({ name: 'gist-sample', isLocalhost: false }) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index f12fcd4209..9d7a1c5b1e 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -54,25 +54,6 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa const promise = createWorkspaceTemplate(workspaceName, workspaceTemplateName) dispatch(createWorkspaceRequest(promise)) promise.then(async () => { - if (isGitRepo) { - let branches = [] - let currentBranch = null - - try { - branches = await getGitRepoBranches(`${plugin.fileProviders.workspace.workspacesPath}/${workspaceName}`) - } catch (e) { - console.error(e) - } - try { - currentBranch = await getGitRepoCurrentBranch(`${plugin.fileProviders.workspace.workspacesPath}/${workspaceName}`) - } catch (e) { - console.error(e) - } - - dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo, branches, currentBranch })) - } else { - dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) - } dispatch(createWorkspaceSuccess({ name: workspaceName, isGitRepo })) await plugin.setWorkspace({ name: workspaceName, isLocalhost: false }) await plugin.setWorkspaces(await getWorkspaces()) @@ -338,9 +319,9 @@ export const uploadFile = async (target, targetFolder: string, cb?: (err: Error, }) } -export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean}[]> | undefined => { +export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }[]> | undefined => { try { - const workspaces: {name: string, isGitRepo: boolean}[] = await new Promise((resolve, reject) => { + const workspaces: {name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string}[] = await new Promise((resolve, reject) => { const workspacesPath = plugin.fileProviders.workspace.workspacesPath plugin.fileProviders.browser.resolveDirectory('/' + workspacesPath, (error, items) => { @@ -350,25 +331,15 @@ export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean Promise.all(Object.keys(items) .filter((item) => items[item].isDirectory) .map(async (folder) => { - console.log('folder: ', folder) const isGitRepo: boolean = await plugin.fileProviders.browser.exists('/' + folder + '/.git') if (isGitRepo) { let branches = [] let currentBranch = null - - try { - branches = await getGitRepoBranches(folder) - } catch (e) { - console.error(e) - } - try { - currentBranch = await getGitRepoCurrentBranch(folder) - } catch (e) { - console.error(e) - } + branches = await getGitRepoBranches(folder) console.log('branches: ', branches) + currentBranch = await getGitRepoCurrentBranch(folder) return { name: folder.replace(workspacesPath + '/', ''), diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index ba78892d51..e664984eca 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -136,6 +136,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => { } case 'SET_WORKSPACES': { + console.log('called SET_WORKSPACES') const payload = action.payload as { name: string; isGitRepo: boolean; branches?: { remote: any; name: string; }[], currentBranch?: string }[] return { diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index e953fcbaea..061279be0e 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -13,7 +13,7 @@ export function Workspace () { const LOCALHOST = ' - connect to localhost - ' const NO_WORKSPACE = ' - none - ' const [currentWorkspace, setCurrentWorkspace] = useState(NO_WORKSPACE) - const [selectedWorkspace, setSelectedWorkspace] = useState<{ name: string, isGitRepo: boolean}>(null) + const [selectedWorkspace, setSelectedWorkspace] = useState<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }>(null) const [showDropdown, setShowDropdown] = useState(false) const [showIconsMenu, hideIconsMenu] = useState(false) const displayOzCustomRef = useRef() @@ -679,22 +679,31 @@ export function Workspace () {
-
-
-
DGIT
-
- - - Main - - - - setup - - + { + selectedWorkspace && +
+
+
DGIT
+
+ + + { selectedWorkspace.currentBranch || '-none-'} + + + + { + (selectedWorkspace.branches || []).map((branch, index) => { + return ( + { selectedWorkspace.currentBranch === branch.name ? ✓ { branch.name } : { branch.name } } + ) + }) + } + + +
-
+ } ) } From 13ef650a917d503ee807c710bd30d1851d0605c0 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 6 Sep 2022 12:15:10 +0100 Subject: [PATCH 05/19] Filter branches list and view all branches on dgit --- apps/remix-ide/src/app/files/dgitProvider.js | 6 +-- .../workspace/src/lib/actions/index.ts | 8 ++++ .../workspace/src/lib/actions/workspace.ts | 1 - .../workspace/src/lib/contexts/index.ts | 3 +- .../src/lib/css/remix-ui-workspace.css | 5 +++ .../src/lib/providers/FileSystemProvider.tsx | 11 ++++- .../workspace/src/lib/remix-ui-workspace.tsx | 43 +++++++++++++++---- 7 files changed, 62 insertions(+), 15 deletions(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index 6f8abe3025..beb8b80c43 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -125,10 +125,10 @@ class DGitProvider extends Plugin { return status } - async remotes () { + async remotes (config) { let remotes = [] try { - remotes = await git.listRemotes({ ...await this.getGitConfig() }) + remotes = await git.listRemotes({ ...config ? config : await this.getGitConfig() }) } catch (e) { // do nothing } @@ -155,7 +155,7 @@ class DGitProvider extends Plugin { async branches (config) { const cmd = config ? config : await this.getGitConfig() - const remotes = await this.remotes() + const remotes = await this.remotes(config) let branches = [] branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } }) for (const remote of remotes) { diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 8c48726c98..66d7ec7bc7 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -488,3 +488,11 @@ export const moveFolder = async (src: string, dest: string) => { dispatch(displayPopUp('Oops! An error ocurred while performing moveDir operation.' + error)) } } + + +export const showAllBranches = async () => { + const isActive = await plugin.call('manager', 'isActive', 'dgit') + + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + plugin.call('menuicons', 'select', 'dgit') +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 9d7a1c5b1e..8800314dc5 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -338,7 +338,6 @@ export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean let currentBranch = null branches = await getGitRepoBranches(folder) - console.log('branches: ', branches) currentBranch = await getGitRepoCurrentBranch(folder) return { diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 2fd6a71b46..5f4cdaee33 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -32,6 +32,7 @@ export const FileSystemContext = createContext<{ dispatchHandleRestoreBackup: () => Promise dispatchCloneRepository: (url: string) => Promise, dispatchMoveFile: (src: string, dest: string) => Promise, - dispatchMoveFolder: (src: string, dest: string) => Promise + dispatchMoveFolder: (src: string, dest: string) => Promise, + dispatchShowAllBranches: () => Promise }>(null) \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css b/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css index 55357dacae..13756a9b94 100644 --- a/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css +++ b/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css @@ -84,6 +84,7 @@ border-radius: .25rem; background: var(--custom-select); } + .custom-dropdown-items a { border-radius: .25rem; text-transform: none; @@ -133,3 +134,7 @@ color: var(--text) } + .checkout-input { + font-size: 10px !important; + } + diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index 2b1409fe86..ddc12cdfdf 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -7,7 +7,9 @@ import { FileSystemContext } from '../contexts' import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, - fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder } from '../actions' + fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, + showAllBranches +} from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Workspace } from '../remix-ui-workspace' @@ -136,6 +138,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { const dispatchMoveFolder = async (src: string, dest: string) => { await moveFolder(src, dest) } + + const dispatchShowAllBranches = async () => { + await showAllBranches() + } useEffect(() => { dispatchInitWorkspace() @@ -241,7 +247,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchHandleRestoreBackup, dispatchCloneRepository, dispatchMoveFile, - dispatchMoveFolder + dispatchMoveFolder, + dispatchShowAllBranches } return ( diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 061279be0e..d100f7ac0f 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -16,6 +16,8 @@ export function Workspace () { const [selectedWorkspace, setSelectedWorkspace] = useState<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }>(null) const [showDropdown, setShowDropdown] = useState(false) const [showIconsMenu, hideIconsMenu] = useState(false) + const [showBranches, setShowBranches] = useState(false) + const [branchFilter, setBranchFilter] = useState('') const displayOzCustomRef = useRef() const mintableCheckboxRef = useRef() const burnableCheckboxRef = useRef() @@ -198,6 +200,18 @@ export function Workspace () { // @ts-ignore workspaceCreateInput.current.value = `${workspaceCreateTemplateInput.current.value + '_upgradeable'}_${Date.now()}` } + + const toggleBranches = (isOpen: boolean) => { + setShowBranches(isOpen) + } + + const handleBranchFilerChange = (branchFilter: string) => { + setBranchFilter(branchFilter) + } + + const showAllBranches = () => { + global.dispatchShowAllBranches() + } const createModalMessage = () => { return ( @@ -685,18 +699,31 @@ export function Workspace () {
DGIT
- + - { selectedWorkspace.currentBranch || '-none-'} + { selectedWorkspace.currentBranch || '-none-' } - + +
+ Switch branches +
{ toggleBranches(false) }}> +
+
+
+ { handleBranchFilerChange(e.target.value) }} /> +
+
+ { + (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 4).map((branch, index) => { + return ( + { selectedWorkspace.currentBranch === branch.name ? ✓ { branch.name } : { branch.name } } + ) + }) + } +
{ - (selectedWorkspace.branches || []).map((branch, index) => { - return ( - { selectedWorkspace.currentBranch === branch.name ? ✓ { branch.name } : { branch.name } } - ) - }) + (selectedWorkspace.branches || []).length > 4 && }
From 3744ac36d2295982381c5bf8b997dbdc29011afb Mon Sep 17 00:00:00 2001 From: David Disu Date: Wed, 7 Sep 2022 09:22:26 +0100 Subject: [PATCH 06/19] Basic checkout implementation --- .../workspace/src/lib/actions/index.ts | 2 +- .../workspace/src/lib/actions/workspace.ts | 37 +++++++++++++++++++ .../workspace/src/lib/contexts/index.ts | 3 +- .../src/lib/providers/FileSystemProvider.tsx | 10 ++++- .../workspace/src/lib/remix-ui-workspace.tsx | 12 +++++- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 66d7ec7bc7..3469c671e6 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -495,4 +495,4 @@ export const showAllBranches = async () => { if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') plugin.call('menuicons', 'select', 'dgit') -} \ No newline at end of file +} diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 8800314dc5..5ee0e9ce28 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -439,3 +439,40 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => { return currentBranch } + +export const showAllBranches = async () => { + const isActive = await plugin.call('manager', 'isActive', 'dgit') + + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + plugin.call('menuicons', 'select', 'dgit') +} + +export const switchToBranch = async (branch: string) => { + const gitConfig = { + ref: branch + } + const promise = plugin.call('dGitProvider', 'checkout', gitConfig) + + dispatch(cloneRepositoryRequest()) + promise.then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(cloneRepositorySuccess()) + }).catch((e) => { + const checkoutModal = { + id: 'checkoutGitBranch', + title: 'Checkout Git Branch', + message: 'An error occurred: ' + e, + modalType: 'modal', + okLabel: 'OK', + okFn: async () => { + // await deleteWorkspace(repoName) + dispatch(cloneRepositoryFailed()) + }, + hideFn: async () => { + // await deleteWorkspace(repoName) + dispatch(cloneRepositoryFailed()) + } + } + plugin.call('notification', 'modal', checkoutModal) + }) +} diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 5f4cdaee33..ac4e6c456d 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -33,6 +33,7 @@ export const FileSystemContext = createContext<{ dispatchCloneRepository: (url: string) => Promise, dispatchMoveFile: (src: string, dest: string) => Promise, dispatchMoveFolder: (src: string, dest: string) => Promise, - dispatchShowAllBranches: () => Promise + dispatchShowAllBranches: () => Promise, + dispatchSwitchToBranch: (branch: string) => Promise }>(null) \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index ddc12cdfdf..22c844a48a 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -8,7 +8,8 @@ import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, - showAllBranches + showAllBranches, + switchToBranch } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -143,6 +144,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await showAllBranches() } + const dispatchSwitchToBranch = async (branch: string) => { + await switchToBranch(branch) + } + useEffect(() => { dispatchInitWorkspace() }, []) @@ -248,7 +253,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchCloneRepository, dispatchMoveFile, dispatchMoveFolder, - dispatchShowAllBranches + dispatchShowAllBranches, + dispatchSwitchToBranch } return ( diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index d100f7ac0f..71416a3337 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -213,6 +213,10 @@ export function Workspace () { global.dispatchShowAllBranches() } + const switchToBranch = (branch: string) => { + global.dispatchSwitchToBranch(branch) + } + const createModalMessage = () => { return ( <> @@ -717,7 +721,13 @@ export function Workspace () { { (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 4).map((branch, index) => { return ( - { selectedWorkspace.currentBranch === branch.name ? ✓ { branch.name } : { branch.name } } + + { + selectedWorkspace.currentBranch === branch.name ? + { switchToBranch(branch.name) }}>✓ { branch.name } : + { switchToBranch(branch.name) }}>{ branch.name } + } + ) }) } From ad06cb9302b9b5783bbfdb34b3e236b7bdb918a6 Mon Sep 17 00:00:00 2001 From: David Disu Date: Thu, 8 Sep 2022 10:07:13 +0100 Subject: [PATCH 07/19] switch branches and checkout to new branch --- apps/remix-ide/src/app/files/dgitProvider.js | 20 +++-- .../workspace/src/lib/actions/index.ts | 8 -- .../workspace/src/lib/actions/workspace.ts | 35 +++++---- .../workspace/src/lib/contexts/index.ts | 3 +- .../src/lib/providers/FileSystemProvider.tsx | 10 ++- .../workspace/src/lib/remix-ui-workspace.tsx | 78 +++++++++++++------ 6 files changed, 93 insertions(+), 61 deletions(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index beb8b80c43..3522188f74 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -107,14 +107,16 @@ class DGitProvider extends Plugin { }, 1000) } - async checkout (cmd) { + async checkout (cmd, refresh = true) { await git.checkout({ ...await this.getGitConfig(), ...cmd }) - setTimeout(async () => { - await this.call('fileManager', 'refresh') - }, 1000) + if (refresh) { + setTimeout(async () => { + await this.call('fileManager', 'refresh') + }, 1000) + } } async log (cmd) { @@ -135,14 +137,16 @@ class DGitProvider extends Plugin { return remotes } - async branch (cmd) { + async branch (cmd, refresh = true) { const status = await git.branch({ ...await this.getGitConfig(), ...cmd }) - setTimeout(async () => { - await this.call('fileManager', 'refresh') - }, 1000) + if (refresh) { + setTimeout(async () => { + await this.call('fileManager', 'refresh') + }, 1000) + } return status } diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 3469c671e6..8c48726c98 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -488,11 +488,3 @@ export const moveFolder = async (src: string, dest: string) => { dispatch(displayPopUp('Oops! An error ocurred while performing moveDir operation.' + error)) } } - - -export const showAllBranches = async () => { - const isActive = await plugin.call('manager', 'isActive', 'dgit') - - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - plugin.call('menuicons', 'select', 'dgit') -} diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 5ee0e9ce28..4bb728139b 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -451,28 +451,29 @@ export const switchToBranch = async (branch: string) => { const gitConfig = { ref: branch } - const promise = plugin.call('dGitProvider', 'checkout', gitConfig) + const promise = plugin.call('dGitProvider', 'checkout', gitConfig, false) dispatch(cloneRepositoryRequest()) promise.then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(cloneRepositorySuccess()) }).catch((e) => { - const checkoutModal = { - id: 'checkoutGitBranch', - title: 'Checkout Git Branch', - message: 'An error occurred: ' + e, - modalType: 'modal', - okLabel: 'OK', - okFn: async () => { - // await deleteWorkspace(repoName) - dispatch(cloneRepositoryFailed()) - }, - hideFn: async () => { - // await deleteWorkspace(repoName) - dispatch(cloneRepositoryFailed()) - } - } - plugin.call('notification', 'modal', checkoutModal) + dispatch(cloneRepositoryFailed()) }) + return promise +} + +export const switchToNewBranch = async (branch: string) => { + const gitConfig = { + ref: branch + } + const promise = plugin.call('dGitProvider', 'branch', gitConfig, false) + + dispatch(cloneRepositoryRequest()) + promise.then(async () => { + dispatch(cloneRepositorySuccess()) + }).catch((e) => { + dispatch(cloneRepositoryFailed()) + }) + return promise } diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index ac4e6c456d..edec716765 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -34,6 +34,7 @@ export const FileSystemContext = createContext<{ dispatchMoveFile: (src: string, dest: string) => Promise, dispatchMoveFolder: (src: string, dest: string) => Promise, dispatchShowAllBranches: () => Promise, - dispatchSwitchToBranch: (branch: string) => Promise + dispatchSwitchToBranch: (branch: string) => Promise, + dispatchSwitchToNewBranch: (branch: string) => Promise }>(null) \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index 22c844a48a..b85b23b838 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -8,8 +8,7 @@ import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, - showAllBranches, - switchToBranch + showAllBranches, switchToBranch, switchToNewBranch } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -148,6 +147,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await switchToBranch(branch) } + const dispatchSwitchToNewBranch = async (branch: string) => { + await switchToNewBranch(branch) + } + useEffect(() => { dispatchInitWorkspace() }, []) @@ -254,7 +257,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchMoveFile, dispatchMoveFolder, dispatchShowAllBranches, - dispatchSwitchToBranch + dispatchSwitchToBranch, + dispatchSwitchToNewBranch } return ( diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 71416a3337..f16a1d0bf4 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef, useContext, SyntheticEvent } from 'react' // eslint-disable-line +import React, { useState, useEffect, useRef, useContext, SyntheticEvent, ChangeEvent, KeyboardEvent } from 'react' // eslint-disable-line import { Dropdown, OverlayTrigger, Tooltip } from 'react-bootstrap' import { CustomIconsToggle, CustomMenu, CustomToggle } from '@remix-ui/helper' import { FileExplorer } from './components/file-explorer' // eslint-disable-line @@ -17,7 +17,8 @@ export function Workspace () { const [showDropdown, setShowDropdown] = useState(false) const [showIconsMenu, hideIconsMenu] = useState(false) const [showBranches, setShowBranches] = useState(false) - const [branchFilter, setBranchFilter] = useState('') + const [branchFilter, setBranchFilter] = useState('') + const [selectedBranch, setSelectedBranch] = useState('') const displayOzCustomRef = useRef() const mintableCheckboxRef = useRef() const burnableCheckboxRef = useRef() @@ -30,6 +31,7 @@ export function Workspace () { const workspaceCreateTemplateInput = useRef() const cloneUrlRef = useRef() const initGitRepoRef = useRef() + const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 20) : [] useEffect(() => { let workspaceName = localStorage.getItem('currentWorkspace') @@ -65,6 +67,7 @@ export function Workspace () { const workspace = global.fs.browser.workspaces.find(workspace => workspace.name === currentWorkspace) setSelectedWorkspace(workspace) + workspace && setSelectedBranch(workspace.currentBranch) }, [currentWorkspace]) const renameCurrentWorkspace = () => { @@ -205,7 +208,9 @@ export function Workspace () { setShowBranches(isOpen) } - const handleBranchFilerChange = (branchFilter: string) => { + const handleBranchFilterChange = (e: ChangeEvent) => { + const branchFilter = e.target.value + setBranchFilter(branchFilter) } @@ -213,8 +218,22 @@ export function Workspace () { global.dispatchShowAllBranches() } - const switchToBranch = (branch: string) => { - global.dispatchSwitchToBranch(branch) + const switchToBranch = async (branch: string) => { + try { + await global.dispatchSwitchToBranch(branch) + setSelectedBranch(branch) + } catch (e) { + global.modal('Checkout Git Branch', e.message, 'OK', () => {}) + } + } + + const switchToNewBranch = async () => { + try { + await global.dispatchSwitchToNewBranch(branchFilter) + setSelectedBranch(branchFilter) + } catch (e) { + global.modal('Checkout Git Branch', e.message, 'OK', () => {}) + } } const createModalMessage = () => { @@ -603,16 +622,17 @@ export function Workspace () {
: { currentWorkspace === name ? ✓ { name } : { name } } } - - )) - } - { ((global.fs.browser.workspaces.length <= 0) || currentWorkspace === NO_WORKSPACE) && { switchWorkspace(NO_WORKSPACE) }}>{ NO_WORKSPACE } } - - -
- -
-
{ toggleDropdown(false) }}> + + )) + } + { switchWorkspace(LOCALHOST) }}>{currentWorkspace === LOCALHOST ? ✓ localhost : { LOCALHOST } } + { ((global.fs.browser.workspaces.length <= 0) || currentWorkspace === NO_WORKSPACE) && { switchWorkspace(NO_WORKSPACE) }}>{ NO_WORKSPACE } } + + +
+ +
+
{ toggleDropdown(false) }}>
{ (global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) &&
} { !(global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) && @@ -705,7 +725,7 @@ export function Workspace () {
- { selectedWorkspace.currentBranch || '-none-' } + { global.fs.browser.isRequestingCloning ? : selectedBranch || '-none-' } @@ -715,21 +735,31 @@ export function Workspace () {
- { handleBranchFilerChange(e.target.value) }} /> +
-
+
{ - (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 4).map((branch, index) => { + filteredBranches.length > 0 ? filteredBranches.map((branch, index) => { return ( - + { switchToBranch(branch.name) }}> { - selectedWorkspace.currentBranch === branch.name ? - { switchToBranch(branch.name) }}>✓ { branch.name } : - { switchToBranch(branch.name) }}>{ branch.name } + selectedBranch === branch.name ? + ✓ { branch.name } : + { branch.name } } ) - }) + }) : + +
+ Create branch: { branchFilter } from '{selectedBranch}' +
+
}
{ From 4fe76cc20138ebc7d3490e58ba79f47a8c7bac40 Mon Sep 17 00:00:00 2001 From: David Disu Date: Fri, 9 Sep 2022 21:04:43 +0100 Subject: [PATCH 08/19] Fix clone bug --- .../workspace/src/lib/actions/payload.ts | 14 +++++++++ .../workspace/src/lib/actions/workspace.ts | 21 ++++++++++--- .../workspace/src/lib/reducers/workspace.ts | 30 +++++++++++++++++++ .../workspace/src/lib/remix-ui-workspace.tsx | 12 ++++---- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/payload.ts b/libs/remix-ui/workspace/src/lib/actions/payload.ts index e9acca3087..eeea274dc2 100644 --- a/libs/remix-ui/workspace/src/lib/actions/payload.ts +++ b/libs/remix-ui/workspace/src/lib/actions/payload.ts @@ -264,3 +264,17 @@ export const cloneRepositoryFailed = () => { type: 'CLONE_REPOSITORY_FAILED' } } + +export const setCurrentWorkspaceBranches = (branches?: { remote: any, name: string }[]) => { + return { + type: 'SET_CURRENT_WORKSPACE_BRANCHES', + payload: branches + } +} + +export const setCurrentWorkspaceCurrentBranch = (currentBranch?: string) => { + return { + type: 'SET_CURRENT_WORKSPACE_CURRENT_BRANCH', + payload: currentBranch + } +} diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 4bb728139b..ecced67abe 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -1,7 +1,7 @@ import React from 'react' import { bufferToHex, keccakFromString } from 'ethereumjs-util' import axios, { AxiosResponse } from 'axios' -import { addInputFieldSuccess, cloneRepositoryFailed, cloneRepositoryRequest, cloneRepositorySuccess, createWorkspaceError, createWorkspaceRequest, createWorkspaceSuccess, displayNotification, displayPopUp, fetchWorkspaceDirectoryError, fetchWorkspaceDirectoryRequest, fetchWorkspaceDirectorySuccess, hideNotification, setCurrentWorkspace, setDeleteWorkspace, setMode, setReadOnlyMode, setRenameWorkspace } from './payload' +import { addInputFieldSuccess, cloneRepositoryFailed, cloneRepositoryRequest, cloneRepositorySuccess, createWorkspaceError, createWorkspaceRequest, createWorkspaceSuccess, displayNotification, displayPopUp, fetchWorkspaceDirectoryError, fetchWorkspaceDirectoryRequest, fetchWorkspaceDirectorySuccess, hideNotification, setCurrentWorkspace, setCurrentWorkspaceBranches, setCurrentWorkspaceCurrentBranch, setDeleteWorkspace, setMode, setReadOnlyMode, setRenameWorkspace } from './payload' import { addSlash, checkSlash, checkSpecialChars } from '@remix-ui/helper' import { JSONStandardInput, WorkspaceTemplate } from '../types' @@ -339,7 +339,6 @@ export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean branches = await getGitRepoBranches(folder) currentBranch = await getGitRepoCurrentBranch(folder) - return { name: folder.replace(workspacesPath + '/', ''), isGitRepo, @@ -377,6 +376,13 @@ export const cloneRepository = async (url: string) => { if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') await fetchWorkspaceDirectory(ROOT_PATH) + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const branches = await getGitRepoBranches(workspacesPath + '/' + repoName) + + dispatch(setCurrentWorkspaceBranches(branches)) + const currentBranch = await getGitRepoCurrentBranch(workspacesPath + '/' + repoName) + + dispatch(setCurrentWorkspaceCurrentBranch(currentBranch)) dispatch(cloneRepositorySuccess()) }).catch(() => { const cloneModal = { @@ -456,8 +462,9 @@ export const switchToBranch = async (branch: string) => { dispatch(cloneRepositoryRequest()) promise.then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) dispatch(cloneRepositorySuccess()) - }).catch((e) => { + }).catch(() => { dispatch(cloneRepositoryFailed()) }) return promise @@ -471,8 +478,14 @@ export const switchToNewBranch = async (branch: string) => { dispatch(cloneRepositoryRequest()) promise.then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const branches = await getGitRepoBranches(workspacesPath + '/' + branch) + + dispatch(setCurrentWorkspaceBranches(branches)) dispatch(cloneRepositorySuccess()) - }).catch((e) => { + }).catch(() => { dispatch(cloneRepositoryFailed()) }) return promise diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index e664984eca..ab982ea269 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -674,6 +674,36 @@ export const browserReducer = (state = browserInitialState, action: Action) => { } } + case 'SET_CURRENT_WORKSPACE_BRANCHES': { + const payload: { remote: any, name: string }[] = action.payload + + return { + ...state, + browser: { + ...state.browser, + workspaces: state.browser.workspaces.map((workspace) => { + if (workspace.name === state.browser.currentWorkspace) workspace.branches = payload + return workspace + }) + } + } + } + + case 'SET_CURRENT_WORKSPACE_CURRENT_BRANCH': { + const payload: string = action.payload + + return { + ...state, + browser: { + ...state.browser, + workspaces: state.browser.workspaces.map((workspace) => { + if (workspace.name === state.browser.currentWorkspace) workspace.currentBranch = payload + return workspace + }) + } + } + } + default: throw new Error() } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index f16a1d0bf4..317b0b0bc0 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -18,7 +18,6 @@ export function Workspace () { const [showIconsMenu, hideIconsMenu] = useState(false) const [showBranches, setShowBranches] = useState(false) const [branchFilter, setBranchFilter] = useState('') - const [selectedBranch, setSelectedBranch] = useState('') const displayOzCustomRef = useRef() const mintableCheckboxRef = useRef() const burnableCheckboxRef = useRef() @@ -32,6 +31,7 @@ export function Workspace () { const cloneUrlRef = useRef() const initGitRepoRef = useRef() const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 20) : [] + const currentBranch = selectedWorkspace ? selectedWorkspace.currentBranch : null useEffect(() => { let workspaceName = localStorage.getItem('currentWorkspace') @@ -67,7 +67,7 @@ export function Workspace () { const workspace = global.fs.browser.workspaces.find(workspace => workspace.name === currentWorkspace) setSelectedWorkspace(workspace) - workspace && setSelectedBranch(workspace.currentBranch) + // workspace && setSelectedBranch(workspace.currentBranch) }, [currentWorkspace]) const renameCurrentWorkspace = () => { @@ -221,7 +221,6 @@ export function Workspace () { const switchToBranch = async (branch: string) => { try { await global.dispatchSwitchToBranch(branch) - setSelectedBranch(branch) } catch (e) { global.modal('Checkout Git Branch', e.message, 'OK', () => {}) } @@ -230,7 +229,6 @@ export function Workspace () { const switchToNewBranch = async () => { try { await global.dispatchSwitchToNewBranch(branchFilter) - setSelectedBranch(branchFilter) } catch (e) { global.modal('Checkout Git Branch', e.message, 'OK', () => {}) } @@ -725,7 +723,7 @@ export function Workspace () {
- { global.fs.browser.isRequestingCloning ? : selectedBranch || '-none-' } + { global.fs.browser.isRequestingCloning ? : currentBranch || '-none-' } @@ -748,7 +746,7 @@ export function Workspace () { return ( { switchToBranch(branch.name) }}> { - selectedBranch === branch.name ? + currentBranch === branch.name ? ✓ { branch.name } : { branch.name } } @@ -757,7 +755,7 @@ export function Workspace () { }) :
- Create branch: { branchFilter } from '{selectedBranch}' + Create branch: { branchFilter } from '{currentBranch}'
} From 0068195b0c317c843f912ddff03ee3c9c7661d77 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 13 Sep 2022 15:30:26 +0100 Subject: [PATCH 09/19] separate local branch from remote branch --- .../workspace/src/lib/actions/workspace.ts | 20 ++++++++++++++++--- .../workspace/src/lib/remix-ui-workspace.tsx | 19 ++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index ecced67abe..898a73d046 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -480,13 +480,27 @@ export const switchToNewBranch = async (branch: string) => { promise.then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) - const workspacesPath = plugin.fileProviders.workspace.workspacesPath - const branches = await getGitRepoBranches(workspacesPath + '/' + branch) + // const workspacesPath = plugin.fileProviders.workspace.workspacesPath + // const branches = await getGitRepoBranches(workspacesPath + '/' + branch) - dispatch(setCurrentWorkspaceBranches(branches)) + // dispatch(setCurrentWorkspaceBranches(branches)) dispatch(cloneRepositorySuccess()) }).catch(() => { dispatch(cloneRepositoryFailed()) }) return promise } + +export const hasLocalChanges = async (branch: string) => { + const staged = await plugin.call('dGitProvider', 'lsfiles', { ref: branch }) + const untracked = await plugin.call('dGitProvider', 'unstagedStatus', { ref: branch }) + const deleted = await plugin.call('dGitProvider', 'deleteStatus', { ref: branch }) + const modified = await plugin.call('dGitProvider', 'modifiedStatus', { ref: branch }) + + console.log('staged: ', staged) + console.log('untracked: ', untracked) + console.log('deleted: ', deleted) + console.log('modified: ', modified) + + return deleted.length > 0 || staged.length > 0 || untracked.length > 0 || modified.length > 0 +} diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 317b0b0bc0..b209584a72 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -30,7 +30,7 @@ export function Workspace () { const workspaceCreateTemplateInput = useRef() const cloneUrlRef = useRef() const initGitRepoRef = useRef() - const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 20) : [] + const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.name !== 'HEAD').slice(0, 20) : [] const currentBranch = selectedWorkspace ? selectedWorkspace.currentBranch : null useEffect(() => { @@ -67,7 +67,6 @@ export function Workspace () { const workspace = global.fs.browser.workspaces.find(workspace => workspace.name === currentWorkspace) setSelectedWorkspace(workspace) - // workspace && setSelectedBranch(workspace.currentBranch) }, [currentWorkspace]) const renameCurrentWorkspace = () => { @@ -218,9 +217,13 @@ export function Workspace () { global.dispatchShowAllBranches() } - const switchToBranch = async (branch: string) => { + const switchToBranch = async (branch: { remote: any, name: string }) => { try { - await global.dispatchSwitchToBranch(branch) + if (branch.remote) { + await global.dispatchSwitchToNewBranch(branch.name) + } else { + await global.dispatchSwitchToBranch(branch.name) + } } catch (e) { global.modal('Checkout Git Branch', e.message, 'OK', () => {}) } @@ -744,11 +747,11 @@ export function Workspace () { { filteredBranches.length > 0 ? filteredBranches.map((branch, index) => { return ( - { switchToBranch(branch.name) }}> + { switchToBranch(branch) }} title={branch.remote ? 'Checkout new branch from remote branch' : 'Checkout to local branch'}> { - currentBranch === branch.name ? - ✓ { branch.name } : - { branch.name } + (currentBranch === branch.name) && !branch.remote ? + { branch.name } : + { branch.remote ? `${branch.remote}/${branch.name}` : branch.name } } ) From d4bc15f479f930ff6c5c3f091360490abb41af2d Mon Sep 17 00:00:00 2001 From: David Disu Date: Wed, 14 Sep 2022 22:03:53 +0100 Subject: [PATCH 10/19] Show dgit option only for git workspace --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index b209584a72..829dc191a4 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -534,7 +534,7 @@ export function Workspace () { return ( <> -
+
@@ -720,7 +720,7 @@ export function Workspace () {
{ selectedWorkspace && -
+
DGIT
From ff367f16d0e56de4b0e8dc7aa86f2a925984673a Mon Sep 17 00:00:00 2001 From: David Disu Date: Fri, 16 Sep 2022 15:02:23 +0100 Subject: [PATCH 11/19] List uncommitted files --- apps/remix-ide/src/app/files/dgitProvider.js | 1 - .../workspace/src/lib/actions/workspace.ts | 80 +++++++++++-------- .../src/lib/utils/gitStatusFilter.ts | 8 ++ 3 files changed, 55 insertions(+), 34 deletions(-) create mode 100644 libs/remix-ui/workspace/src/lib/utils/gitStatusFilter.ts diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index 3522188f74..c8e8753ad1 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -9,7 +9,6 @@ import { saveAs } from 'file-saver' import http from 'isomorphic-git/http/web' -import { IndexedDBStorage } from './filesystems/indexedDB' const JSZip = require('jszip') const path = require('path') diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 898a73d046..c99ffd9e1e 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -10,6 +10,7 @@ import * as templateWithContent from '@remix-project/remix-ws-templates' import { ROOT_PATH } from '../utils/constants' // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB' +import { getUncommittedFiles } from '../utils/gitStatusFilter' declare global { interface Window { remixFileSystemCallback: IndexedDBStorage; } @@ -431,7 +432,7 @@ export const getGitRepoBranches = async (workspacePath: string) => { fs: window.remixFileSystemCallback, dir: addSlash(workspacePath) } - const branches: { remote: any; name: string; }[] = await plugin.call('dGitProvider', 'branches', gitConfig) + const branches: { remote: any; name: string; }[] = await plugin.call('dGitProvider', 'branches', { ...gitConfig }) return branches } @@ -441,7 +442,7 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => { fs: window.remixFileSystemCallback, dir: addSlash(workspaceName) } - const currentBranch: string = await plugin.call('dGitProvider', 'currentbranch', gitConfig) + const currentBranch: string = await plugin.call('dGitProvider', 'currentbranch', { ...gitConfig }) return currentBranch } @@ -454,36 +455,56 @@ export const showAllBranches = async () => { } export const switchToBranch = async (branch: string) => { - const gitConfig = { - ref: branch + const localChanges = await hasLocalChanges() + + if (Array.isArray(localChanges) && localChanges.length > 0) { + const cloneModal = { + id: 'switchBranch', + title: 'Switch Git Branch', + message: `Your local changes to the following files would be overwritten by checkout.\n + ${localChanges.join('\n')}\n + Do you want to continue?`, + modalType: 'modal', + okLabel: 'Force Checkout', + okFn: async () => { + dispatch(cloneRepositoryRequest()) + plugin.call('dGitProvider', 'checkout', { ref: branch, force: true }, false).then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) + dispatch(cloneRepositorySuccess()) + }).catch(() => { + dispatch(cloneRepositoryFailed()) + }) + }, + cancelLabel: 'Cancel', + cancelFn: () => {}, + hideFn: () => {} + } + plugin.call('notification', 'modal', cloneModal) + } else { + dispatch(cloneRepositoryRequest()) + plugin.call('dGitProvider', 'checkout', { ref: branch, force: true }, false).then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) + dispatch(cloneRepositorySuccess()) + }).catch(() => { + dispatch(cloneRepositoryFailed()) + }) } - const promise = plugin.call('dGitProvider', 'checkout', gitConfig, false) - - dispatch(cloneRepositoryRequest()) - promise.then(async () => { - await fetchWorkspaceDirectory(ROOT_PATH) - dispatch(setCurrentWorkspaceCurrentBranch(branch)) - dispatch(cloneRepositorySuccess()) - }).catch(() => { - dispatch(cloneRepositoryFailed()) - }) - return promise } export const switchToNewBranch = async (branch: string) => { - const gitConfig = { - ref: branch - } - const promise = plugin.call('dGitProvider', 'branch', gitConfig, false) + const promise = plugin.call('dGitProvider', 'branch', { ref: branch }, false) dispatch(cloneRepositoryRequest()) promise.then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) - // const workspacesPath = plugin.fileProviders.workspace.workspacesPath - // const branches = await getGitRepoBranches(workspacesPath + '/' + branch) + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const workspaceName = plugin.fileProviders.workspace.workspace + const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) - // dispatch(setCurrentWorkspaceBranches(branches)) + dispatch(setCurrentWorkspaceBranches(branches)) dispatch(cloneRepositorySuccess()) }).catch(() => { dispatch(cloneRepositoryFailed()) @@ -491,16 +512,9 @@ export const switchToNewBranch = async (branch: string) => { return promise } -export const hasLocalChanges = async (branch: string) => { - const staged = await plugin.call('dGitProvider', 'lsfiles', { ref: branch }) - const untracked = await plugin.call('dGitProvider', 'unstagedStatus', { ref: branch }) - const deleted = await plugin.call('dGitProvider', 'deleteStatus', { ref: branch }) - const modified = await plugin.call('dGitProvider', 'modifiedStatus', { ref: branch }) - - console.log('staged: ', staged) - console.log('untracked: ', untracked) - console.log('deleted: ', deleted) - console.log('modified: ', modified) +export const hasLocalChanges = async () => { + const filesStatus = await plugin.call('dGitProvider', 'status') + const uncommittedFiles = getUncommittedFiles(filesStatus) - return deleted.length > 0 || staged.length > 0 || untracked.length > 0 || modified.length > 0 + return uncommittedFiles } diff --git a/libs/remix-ui/workspace/src/lib/utils/gitStatusFilter.ts b/libs/remix-ui/workspace/src/lib/utils/gitStatusFilter.ts new file mode 100644 index 0000000000..1b95e12538 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/utils/gitStatusFilter.ts @@ -0,0 +1,8 @@ +const FILE = 0, HEAD = 1, WORKDIR = 2, STAGE = 3 + +export const getUncommittedFiles = (statusMatrix: Array>) => { + statusMatrix = statusMatrix.filter(row => (row[HEAD] !== row[WORKDIR]) || (row[HEAD] !== row[STAGE])) + const uncommitedFiles = statusMatrix.map(row => row[FILE]) + + return uncommitedFiles +} \ No newline at end of file From c0952b0053ed88b9af2f604a50c5f0e54d792fb1 Mon Sep 17 00:00:00 2001 From: David Disu Date: Thu, 29 Sep 2022 07:51:49 +0100 Subject: [PATCH 12/19] Fixed switching to remote branches --- .../workspace/src/lib/actions/workspace.ts | 58 +++++++++++++++++-- .../workspace/src/lib/contexts/index.ts | 3 +- .../src/lib/providers/FileSystemProvider.tsx | 15 +++-- .../workspace/src/lib/remix-ui-workspace.tsx | 5 +- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index c99ffd9e1e..f1a3dfbcb6 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -61,13 +61,12 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa await plugin.workspaceCreated(workspaceName) if (isGitRepo) { - await plugin.call('dGitProvider', 'init') + await plugin.call('dGitProvider', 'init', { branch: 'main' }) const isActive = await plugin.call('manager', 'isActive', 'dgit') if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') } if (!isEmpty) await loadWorkspacePreset(workspaceTemplateName, opts) - cb && cb(null, workspaceName) }).catch((error) => { dispatch(createWorkspaceError({ error })) @@ -454,7 +453,7 @@ export const showAllBranches = async () => { plugin.call('menuicons', 'select', 'dgit') } -export const switchToBranch = async (branch: string) => { +export const switchBranch = async (branch: string) => { const localChanges = await hasLocalChanges() if (Array.isArray(localChanges) && localChanges.length > 0) { @@ -493,8 +492,8 @@ export const switchToBranch = async (branch: string) => { } } -export const switchToNewBranch = async (branch: string) => { - const promise = plugin.call('dGitProvider', 'branch', { ref: branch }, false) +export const createNewBranch = async (branch: string) => { + const promise = plugin.call('dGitProvider', 'branch', { ref: branch, checkout: true }, false) dispatch(cloneRepositoryRequest()) promise.then(async () => { @@ -512,6 +511,55 @@ export const switchToNewBranch = async (branch: string) => { return promise } +export const checkoutRemoteBranch = async (branch: string, remote: string) => { + const localChanges = await hasLocalChanges() + + if (Array.isArray(localChanges) && localChanges.length > 0) { + const cloneModal = { + id: 'checkoutRemoteBranch', + title: 'Checkout Remote Branch', + message: `Your local changes to the following files would be overwritten by checkout.\n + ${localChanges.join('\n')}\n + Do you want to continue?`, + modalType: 'modal', + okLabel: 'Force Checkout', + okFn: async () => { + dispatch(cloneRepositoryRequest()) + plugin.call('dGitProvider', 'checkout', { ref: branch, remote, force: true }, false).then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const workspaceName = plugin.fileProviders.workspace.workspace + const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) + + dispatch(setCurrentWorkspaceBranches(branches)) + dispatch(cloneRepositorySuccess()) + }).catch(() => { + dispatch(cloneRepositoryFailed()) + }) + }, + cancelLabel: 'Cancel', + cancelFn: () => {}, + hideFn: () => {} + } + plugin.call('notification', 'modal', cloneModal) + } else { + dispatch(cloneRepositoryRequest()) + plugin.call('dGitProvider', 'checkout', { ref: branch, remote, force: true }, false).then(async () => { + await fetchWorkspaceDirectory(ROOT_PATH) + dispatch(setCurrentWorkspaceCurrentBranch(branch)) + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const workspaceName = plugin.fileProviders.workspace.workspace + const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) + + dispatch(setCurrentWorkspaceBranches(branches)) + dispatch(cloneRepositorySuccess()) + }).catch(() => { + dispatch(cloneRepositoryFailed()) + }) + } +} + export const hasLocalChanges = async () => { const filesStatus = await plugin.call('dGitProvider', 'status') const uncommittedFiles = getUncommittedFiles(filesStatus) diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index edec716765..2e199c2f60 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -35,6 +35,7 @@ export const FileSystemContext = createContext<{ dispatchMoveFolder: (src: string, dest: string) => Promise, dispatchShowAllBranches: () => Promise, dispatchSwitchToBranch: (branch: string) => Promise, - dispatchSwitchToNewBranch: (branch: string) => Promise + dispatchCreateNewBranch: (branch: string) => Promise, + dispatchCheckoutRemoteBranch: (branch: string, remote: string) => Promise }>(null) \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index b85b23b838..2b01004d50 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -8,7 +8,7 @@ import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, - showAllBranches, switchToBranch, switchToNewBranch + showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -144,11 +144,15 @@ export const FileSystemProvider = (props: WorkspaceProps) => { } const dispatchSwitchToBranch = async (branch: string) => { - await switchToBranch(branch) + await switchBranch(branch) } - const dispatchSwitchToNewBranch = async (branch: string) => { - await switchToNewBranch(branch) + const dispatchCreateNewBranch = async (branch: string) => { + await createNewBranch(branch) + } + + const dispatchCheckoutRemoteBranch = async (branch: string, remote: string) => { + await checkoutRemoteBranch(branch, remote) } useEffect(() => { @@ -258,7 +262,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchMoveFolder, dispatchShowAllBranches, dispatchSwitchToBranch, - dispatchSwitchToNewBranch + dispatchCreateNewBranch, + dispatchCheckoutRemoteBranch } return ( diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 829dc191a4..4789d73f48 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -220,18 +220,19 @@ export function Workspace () { const switchToBranch = async (branch: { remote: any, name: string }) => { try { if (branch.remote) { - await global.dispatchSwitchToNewBranch(branch.name) + await global.dispatchCheckoutRemoteBranch(branch.name, branch.remote) } else { await global.dispatchSwitchToBranch(branch.name) } } catch (e) { + console.error(e) global.modal('Checkout Git Branch', e.message, 'OK', () => {}) } } const switchToNewBranch = async () => { try { - await global.dispatchSwitchToNewBranch(branchFilter) + await global.dispatchCreateNewBranch(branchFilter) } catch (e) { global.modal('Checkout Git Branch', e.message, 'OK', () => {}) } From e36ae2792fe72d792868a441efccb6c1bbc31267 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Wed, 28 Sep 2022 12:35:14 +0200 Subject: [PATCH 13/19] Cherry pick Filips fixes --- apps/remix-ide/src/app/files/dgitProvider.js | 6 ++++++ .../workspace/src/lib/actions/workspace.ts | 16 ++++++++++++++++ .../workspace/src/lib/remix-ui-workspace.tsx | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index c8e8753ad1..c49172abe8 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -116,6 +116,7 @@ class DGitProvider extends Plugin { await this.call('fileManager', 'refresh') }, 1000) } + this.emit('checkout') } async log (cmd) { @@ -146,6 +147,7 @@ class DGitProvider extends Plugin { await this.call('fileManager', 'refresh') }, 1000) } + this.emit('branch') return status } @@ -389,6 +391,8 @@ class DGitProvider extends Plugin { pinata_api_key: pinataApiKey, pinata_secret_api_key: pinataSecretApiKey } + }).catch((e) => { + console.log(e) }) // also commit to remix IPFS for availability after pinning to Pinata return await this.export(this.remixIPFS) || result.data.IpfsHash @@ -407,6 +411,8 @@ class DGitProvider extends Plugin { pinata_api_key: pinataApiKey, pinata_secret_api_key: pinataSecretApiKey } + }).catch((e) => { + console.log('Pinata unreachable') }) return result.data } catch (error) { diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index f1a3dfbcb6..4b6b601553 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -26,6 +26,13 @@ let plugin, dispatch: React.Dispatch export const setPlugin = (filePanelPlugin, reducerDispatch) => { plugin = filePanelPlugin dispatch = reducerDispatch + plugin.on('dGitProvider', 'checkout', async () => { + const currentBranch = await plugin.call('dGitProvider', 'currentbranch') + dispatch(setCurrentWorkspaceCurrentBranch(currentBranch)) + }) + plugin.on('dGitProvider', 'branch', async () => { + await refreshBranches() + }) } export const addInputField = async (type: 'file' | 'folder', path: string, cb?: (err: Error, result?: string | number | boolean | Record) => void) => { @@ -453,7 +460,16 @@ export const showAllBranches = async () => { plugin.call('menuicons', 'select', 'dgit') } +const refreshBranches = async () => { + const workspacesPath = plugin.fileProviders.workspace.workspacesPath + const workspaceName = plugin.fileProviders.workspace.workspace + const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) + + dispatch(setCurrentWorkspaceBranches(branches)) +} + export const switchBranch = async (branch: string) => { + await plugin.call('fileManager', 'closeAllFiles') const localChanges = await hasLocalChanges() if (Array.isArray(localChanges) && localChanges.length > 0) { diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 4789d73f48..2abb7d292f 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -217,7 +217,7 @@ export function Workspace () { global.dispatchShowAllBranches() } - const switchToBranch = async (branch: { remote: any, name: string }) => { + const switchToBranch = async (branch: { remote: string, name: string }) => { try { if (branch.remote) { await global.dispatchCheckoutRemoteBranch(branch.name, branch.remote) From 486771366e462cda607f2343c8d3025562dcfb0c Mon Sep 17 00:00:00 2001 From: David Disu Date: Thu, 29 Sep 2022 08:28:02 +0100 Subject: [PATCH 14/19] set default branch name --- libs/remix-ui/workspace/src/lib/actions/workspace.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 4b6b601553..b5f5ce551f 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -69,6 +69,7 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa if (isGitRepo) { await plugin.call('dGitProvider', 'init', { branch: 'main' }) + dispatch(setCurrentWorkspaceCurrentBranch('main')) const isActive = await plugin.call('manager', 'isActive', 'dgit') if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') From 918ee8e4df4ca91711ff6ff3a4b9e67c0c7e63eb Mon Sep 17 00:00:00 2001 From: David Disu Date: Thu, 29 Sep 2022 09:05:35 +0100 Subject: [PATCH 15/19] Activate dgit for git workspaces --- apps/remix-ide/src/app/files/fileManager.ts | 4 ++-- libs/remix-ui/workspace/src/lib/actions/index.ts | 14 +++++++++++++- .../workspace/src/lib/actions/workspace.ts | 7 ++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index 847d6f3f02..d6f5fd9e4b 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -818,8 +818,8 @@ class FileManager extends Plugin { } } - async isGitRepo (directory: string): Promise { - const path = directory + '/.git' + async isGitRepo (): Promise { + const path = '.git' const exists = await this.exists(path) return exists diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 8c48726c98..4201589615 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -38,6 +38,11 @@ const basicWorkspaceInit = async (workspaces: { name: string; isGitRepo: boolean workspaceProvider.setWorkspace(workspaceName) plugin.setWorkspace({ name: workspaceName, isLocalhost: false }) + if (workspace.isGitRepo) { + const isActive = await plugin.call('manager', 'isActive', 'dgit') + + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + } dispatch(setCurrentWorkspace(workspace)) } } @@ -123,7 +128,14 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. const name = localStorage.getItem("currentWorkspace") workspaceProvider.setWorkspace(name) plugin.setWorkspace({ name: name, isLocalhost: false }) - dispatch(setCurrentWorkspace({ name: name, isGitRepo: false })) + const isGitRepo = await plugin.fileManager.isGitRepo() + + if (isGitRepo) { + const isActive = await plugin.call('manager', 'isActive', 'dgit') + + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + } + dispatch(setCurrentWorkspace({ name: name, isGitRepo })) } } else { await basicWorkspaceInit(workspaces, workspaceProvider) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index b5f5ce551f..db6ff0804b 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -277,8 +277,13 @@ export const switchToWorkspace = async (name: string) => { if (isActive) await plugin.call('manager', 'deactivatePlugin', 'remixd') await plugin.fileProviders.workspace.setWorkspace(name) await plugin.setWorkspace({ name, isLocalhost: false }) - const isGitRepo = await plugin.fileManager.isGitRepo(name) + const isGitRepo = await plugin.fileManager.isGitRepo() + if (isGitRepo) { + const isActive = await plugin.call('manager', 'isActive', 'dgit') + + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + } dispatch(setMode('browser')) dispatch(setCurrentWorkspace({ name, isGitRepo })) dispatch(setReadOnlyMode(false)) From 1034486e396ef06b70312df5478b15fdf18179dd Mon Sep 17 00:00:00 2001 From: David Disu Date: Fri, 30 Sep 2022 05:21:52 +0100 Subject: [PATCH 16/19] Allow fallback to default config --- apps/remix-ide/src/app/files/dgitProvider.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/files/dgitProvider.js b/apps/remix-ide/src/app/files/dgitProvider.js index c49172abe8..d3e60a954e 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.js +++ b/apps/remix-ide/src/app/files/dgitProvider.js @@ -50,6 +50,8 @@ class DGitProvider extends Plugin { async getGitConfig () { const workspace = await this.call('filePanel', 'getCurrentWorkspace') + + if (!workspace) return return { fs: window.remixFileSystemCallback, dir: addSlash(workspace.absolutePath) @@ -152,14 +154,16 @@ class DGitProvider extends Plugin { } async currentbranch (config) { - const cmd = config ? config : await this.getGitConfig() + const defaultConfig = await this.getGitConfig() + const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const name = await git.currentBranch(cmd) return name } async branches (config) { - const cmd = config ? config : await this.getGitConfig() + const defaultConfig = await this.getGitConfig() + const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const remotes = await this.remotes(config) let branches = [] branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } }) From 902824dc8a50d2202b054764c395915b4de639d5 Mon Sep 17 00:00:00 2001 From: David Disu Date: Fri, 30 Sep 2022 05:27:03 +0100 Subject: [PATCH 17/19] Removed activating dgit on initialization --- libs/remix-ui/workspace/src/lib/actions/index.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 4201589615..8c48726c98 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -38,11 +38,6 @@ const basicWorkspaceInit = async (workspaces: { name: string; isGitRepo: boolean workspaceProvider.setWorkspace(workspaceName) plugin.setWorkspace({ name: workspaceName, isLocalhost: false }) - if (workspace.isGitRepo) { - const isActive = await plugin.call('manager', 'isActive', 'dgit') - - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - } dispatch(setCurrentWorkspace(workspace)) } } @@ -128,14 +123,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. const name = localStorage.getItem("currentWorkspace") workspaceProvider.setWorkspace(name) plugin.setWorkspace({ name: name, isLocalhost: false }) - const isGitRepo = await plugin.fileManager.isGitRepo() - - if (isGitRepo) { - const isActive = await plugin.call('manager', 'isActive', 'dgit') - - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - } - dispatch(setCurrentWorkspace({ name: name, isGitRepo })) + dispatch(setCurrentWorkspace({ name: name, isGitRepo: false })) } } else { await basicWorkspaceInit(workspaces, workspaceProvider) From e6ab0bda59b4c9163ae7479ebde2eb7aa353dd55 Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 24 Oct 2022 18:28:50 +0100 Subject: [PATCH 18/19] Align git options to base of file-explorer --- .../workspace/src/lib/remix-ui-workspace.tsx | 446 +++++++++--------- 1 file changed, 223 insertions(+), 223 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 2abb7d292f..061283c055 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -534,246 +534,246 @@ export function Workspace () { ] return ( - <> -
-
-
-
-
-
- - - - - - Create - - } - > -
+
+
{ toggleDropdown(false) }}> +
+ { (global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) &&
} + { !(global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) && + (global.fs.mode === 'browser') && (currentWorkspace !== NO_WORKSPACE) && +
+
- -
-
{ toggleDropdown(false) }}> -
- { (global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) &&
} - { !(global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) && - (global.fs.mode === 'browser') && (currentWorkspace !== NO_WORKSPACE) && -
-
} + { (global.fs.mode === 'localhost' && global.fs.localhost.isSuccessfulLocalhost) && +
+ +
+ }
- } - { global.fs.localhost.isRequestingLocalhost &&
} - { (global.fs.mode === 'localhost' && global.fs.localhost.isSuccessfulLocalhost) && -
- -
- }
-
-
- { - selectedWorkspace && -
-
-
DGIT
-
- - - { global.fs.browser.isRequestingCloning ? : currentBranch || '-none-' } - - - -
- Switch branches -
{ toggleBranches(false) }}> +
+ { + selectedWorkspace && +
+
+
GIT
+
+ + + { global.fs.browser.isRequestingCloning ? : currentBranch || '-none-' } + + + +
+ Switch branches +
{ toggleBranches(false) }}> +
+
+
+ +
+
+ { + filteredBranches.length > 0 ? filteredBranches.map((branch, index) => { + return ( + { switchToBranch(branch) }} title={branch.remote ? 'Checkout new branch from remote branch' : 'Checkout to local branch'}> + { + (currentBranch === branch.name) && !branch.remote ? + { branch.name } : + { branch.remote ? `${branch.remote}/${branch.name}` : branch.name } + } + + ) + }) : + +
+ Create branch: { branchFilter } from '{currentBranch}' +
+
+ }
-
-
- -
-
{ - filteredBranches.length > 0 ? filteredBranches.map((branch, index) => { - return ( - { switchToBranch(branch) }} title={branch.remote ? 'Checkout new branch from remote branch' : 'Checkout to local branch'}> - { - (currentBranch === branch.name) && !branch.remote ? - { branch.name } : - { branch.remote ? `${branch.remote}/${branch.name}` : branch.name } - } - - ) - }) : - -
- Create branch: { branchFilter } from '{currentBranch}' -
-
+ (selectedWorkspace.branches || []).length > 4 && } -
- { - (selectedWorkspace.branches || []).length > 4 && - } - - + + +
-
- } - + } +
) } From c027a2b9fcff6281b3c422202f54e23bc3709a57 Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 24 Oct 2022 18:47:30 +0100 Subject: [PATCH 19/19] Ensure Git options is fixed to bottom --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 061283c055..473460382e 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -535,7 +535,7 @@ export function Workspace () { return (
-
+