diff --git a/src/helper/constants.ts b/src/helper/constants.ts index f5a1817..47e4362 100644 --- a/src/helper/constants.ts +++ b/src/helper/constants.ts @@ -1,22 +1,27 @@ -import { SettingSchemaDesc } from "@logseq/libs/dist/LSPlugin.user" +import { SettingSchemaDesc } from "@logseq/libs/dist/LSPlugin.user"; export const COMMON_STYLE = ` #injected-ui-item-git-logseq-git { position: relative; } -#injected-ui-item-git-logseq-git #logseq-git--git #plugin-git-content-wrapper { - position: absolute; - top: 36px; - left: 50%; - transform: translateX(-50%); +.plugin-git-container .plugin-git-mask { + position: fixed; + width: 100vw; + height: 100vh; + left: 0; + top: 0; + z-index: 99; +} +.plugin-git-container .plugin-git-popup { + position: fixed; + z-index: 99; background-color: var(--ls-secondary-background-color); padding: 10px; border-radius: .375rem; --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); box-shadow: var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow); - display: none; } -#injected-ui-item-git-logseq-git #logseq-git--git #plugin-git-content-wrapper::before { +.plugin-git-container .plugin-git-popup::before { content: ''; position: absolute; top: -8px; @@ -28,33 +33,25 @@ export const COMMON_STYLE = ` border-width: 0 10px 8px 10px; border-color: transparent transparent var(--ls-secondary-background-color) transparent; } -#injected-ui-item-git-logseq-git #logseq-git--git #plugin-git-content-wrapper .plugin-git-mask { - position: absolute; - z-index: -1; - width: 100vw; - height: 100vh; - top: -36px; - left: -70vw; -} -` +`; export const SHOW_POPUP_STYLE = ` -#injected-ui-item-git-logseq-git #logseq-git--git #plugin-git-content-wrapper { +.plugin-git-container { display: block; } -` +`; export const HIDE_POPUP_STYLE = ` -#injected-ui-item-git-logseq-git #logseq-git--git #plugin-git-content-wrapper { +.plugin-git-container { display: none; } -` +`; export const INACTIVE_STYLE = ` ${COMMON_STYLE} #injected-ui-item-git-logseq-git::after { display: none; } -` +`; export const ACTIVE_STYLE = ` ${COMMON_STYLE} #injected-ui-item-git-logseq-git::after { @@ -68,7 +65,7 @@ ${COMMON_STYLE} right: 8px; top: 6px; } -` +`; export const LOADING_STYLE = ` ${COMMON_STYLE} @@ -95,48 +92,49 @@ ${COMMON_STYLE} opacity: 0; } } -` +`; export const BUTTONS = [ - { key: 'status', title: 'Check Status', event: 'check' }, - { key: 'log', title: 'Show Log', event: 'log' }, - { key: 'pull', title: 'Pull', event: 'pull' }, - { key: 'pullRebase', title: 'Pull Rebase', event: 'pullRebase' }, - { key: 'checkout', title: 'Checkout', event: 'checkout' }, - { key: 'commit', title: 'Commit', event: 'commit' }, - { key: 'push', title: 'Push', event: 'push' }, - { key: 'commitAndPush', title: 'Commit & Push', event: 'commitAndPush' }, -] + { key: "status", title: "Check Status", event: "check" }, + { key: "log", title: "Show Log", event: "log" }, + { key: "pull", title: "Pull", event: "pull" }, + { key: "pullRebase", title: "Pull Rebase", event: "pullRebase" }, + { key: "checkout", title: "Checkout", event: "checkout" }, + { key: "commit", title: "Commit", event: "commit" }, + { key: "push", title: "Push", event: "push" }, + { key: "commitAndPush", title: "Commit & Push", event: "commitAndPush" }, +]; export const SETTINGS_SCHEMA: SettingSchemaDesc[] = [ { - key: 'buttons', - title: 'Buttons', - type: 'enum', - default: ['Check Status', 'Show Log', 'Pull Rebase', 'Commit & Push'], - description: 'Select buttons to show', - enumPicker: 'checkbox', + key: "buttons", + title: "Buttons", + type: "enum", + default: ["Check Status", "Show Log", "Pull Rebase", "Commit & Push"], + description: "Select buttons to show", + enumPicker: "checkbox", enumChoices: BUTTONS.map(({ title }) => title), }, { - key: 'checkWhenDBChanged', - title: 'Check Status when DB Changed', - type: 'boolean', + key: "checkWhenDBChanged", + title: "Check Status when DB Changed", + type: "boolean", default: true, - description: 'Check status when DB changed, restart logseq to take effect', + description: "Check status when DB changed, restart logseq to take effect", }, { - key: 'autoCheckSynced', - title: 'Auto Check If Synced', - type: 'boolean', + key: "autoCheckSynced", + title: "Auto Check If Synced", + type: "boolean", default: false, - description: 'Automatically check if the local version is the same as the remote', + description: + "Automatically check if the local version is the same as the remote", }, { - key: 'autoPush', - title: 'Auto Push', - type: 'boolean', + key: "autoPush", + title: "Auto Push", + type: "boolean", default: false, - description: 'Auto push when logseq hide', + description: "Auto push when logseq hide", }, -] \ No newline at end of file +]; diff --git a/src/helper/util.ts b/src/helper/util.ts index 9920a72..4405a82 100644 --- a/src/helper/util.ts +++ b/src/helper/util.ts @@ -1,66 +1,86 @@ -import { ACTIVE_STYLE, HIDE_POPUP_STYLE, INACTIVE_STYLE, SHOW_POPUP_STYLE } from './constants' -import { status } from './git' +import { + ACTIVE_STYLE, + HIDE_POPUP_STYLE, + INACTIVE_STYLE, + SHOW_POPUP_STYLE, +} from "./constants"; +import { status } from "./git"; export const checkStatus = async () => { - console.log('Checking status...') - const statusRes = await status(false) - if (statusRes?.stdout === '') { - console.log('No changes', statusRes) - setPluginStyle(INACTIVE_STYLE) + console.log("Checking status..."); + const statusRes = await status(false); + if (statusRes?.stdout === "") { + console.log("No changes", statusRes); + setPluginStyle(INACTIVE_STYLE); } else { - console.log('Need save', statusRes) - setPluginStyle(ACTIVE_STYLE) + console.log("Need save", statusRes); + setPluginStyle(ACTIVE_STYLE); } - return statusRes -} + return statusRes; +}; -let pluginStyle = '' +let pluginStyle = ""; export const setPluginStyle = (style: string) => { - pluginStyle = style - logseq.provideStyle({ key: 'git', style }) -} -export const getPluginStyle = () => pluginStyle - + pluginStyle = style; + logseq.provideStyle({ key: "git", style }); +}; +export const getPluginStyle = () => pluginStyle; export const showPopup = () => { - const _style = getPluginStyle() - setPluginStyle(`${_style}\n${SHOW_POPUP_STYLE}`) -} + const _style = getPluginStyle(); + logseq.App.queryElementRect("#logseq-git--git").then((triggerIconRect) => { + console.log("[faiz:] === triggerIconRect", triggerIconRect); + if (!triggerIconRect) return; + const popupWidth = 120 + 10 * 2; + const left = + triggerIconRect.left + triggerIconRect.width / 2 - popupWidth / 2; + const top = triggerIconRect.top + triggerIconRect.height; + const _style = getPluginStyle(); + setPluginStyle( + `${_style}\n.plugin-git-popup{left:${left}px;top:${top}px;}` + ); + }); + setPluginStyle(`${_style}\n${SHOW_POPUP_STYLE}`); +}; export const hidePopup = () => { - const _style = getPluginStyle() - setPluginStyle(`${_style}\n${HIDE_POPUP_STYLE}`) -} - + const _style = getPluginStyle(); + setPluginStyle(`${_style}\n${HIDE_POPUP_STYLE}`); +}; export const debounce = (fn, wait: number = 100, environment?: any) => { - let timer = null - return function() { + let timer = null; + return function () { // @ts-ignore - const context = environment || this - const args = arguments + const context = environment || this; + const args = arguments; if (timer) { - clearTimeout(timer) - timer = null + clearTimeout(timer); + timer = null; } // @ts-ignore timer = setTimeout(function () { - fn.apply(context, args) - }, wait) - } -} + fn.apply(context, args); + }, wait); + }; +}; export const checkStatusWithDebounce = debounce(() => { - checkStatus() -}, 2000) + checkStatus(); +}, 2000); export const isRepoUpTodate = async () => { - await logseq.Git.execCommand(['fetch']) - const local = await logseq.Git.execCommand(['rev-parse', 'HEAD']) - const remote = await logseq.Git.execCommand(['rev-parse', '@{u}']) - return local.stdout === remote.stdout -} + await logseq.Git.execCommand(["fetch"]); + const local = await logseq.Git.execCommand(["rev-parse", "HEAD"]); + const remote = await logseq.Git.execCommand(["rev-parse", "@{u}"]); + return local.stdout === remote.stdout; +}; export const checkIsSynced = async () => { - const isSynced = await isRepoUpTodate() - if (!isSynced) logseq.UI.showMsg(`The current repository is not synchronized with the remote repository, please check.`, 'warning', { timeout: 0 }) -} \ No newline at end of file + const isSynced = await isRepoUpTodate(); + if (!isSynced) + logseq.UI.showMsg( + `The current repository is not synchronized with the remote repository, please check.`, + "warning", + { timeout: 0 } + ); +}; diff --git a/src/main.tsx b/src/main.tsx index 631fcce..b8e90e6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,147 +1,193 @@ -import '@logseq/libs' -import React from 'react' -import ReactDOM from 'react-dom' -import App from './App' -import { BUTTONS, LOADING_STYLE, SETTINGS_SCHEMA } from './helper/constants' -import { checkout, commit, log, pull, pullRebase, push, status } from './helper/git' -import { checkStatus, debounce, hidePopup, setPluginStyle, showPopup, checkIsSynced, checkStatusWithDebounce } from './helper/util' -import './index.css' +import "@logseq/libs"; +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App"; +import { BUTTONS, LOADING_STYLE, SETTINGS_SCHEMA } from "./helper/constants"; +import { + checkout, + commit, + log, + pull, + pullRebase, + push, + status, +} from "./helper/git"; +import { + checkStatus, + debounce, + hidePopup, + setPluginStyle, + showPopup, + checkIsSynced, + checkStatusWithDebounce, + getPluginStyle, +} from "./helper/util"; +import "./index.css"; -const isDevelopment = import.meta.env.DEV +const isDevelopment = import.meta.env.DEV; if (isDevelopment) { - renderApp('browser') + renderApp("browser"); } else { - console.log('=== logseq-plugin-git loaded ===') + console.log("=== logseq-plugin-git loaded ==="); logseq.ready(() => { - const operations = { - check: debounce(async function() { - const status = await checkStatus() - if (status?.stdout === '') { - logseq.UI.showMsg('No changes detected.') + check: debounce(async function () { + const status = await checkStatus(); + if (status?.stdout === "") { + logseq.UI.showMsg("No changes detected."); } else { - logseq.UI.showMsg('Changes detected:\n' + status.stdout, 'success', { timeout: 0 }) + logseq.UI.showMsg("Changes detected:\n" + status.stdout, "success", { + timeout: 0, + }); } - hidePopup() + hidePopup(); }), - pull: debounce(async function() { - console.log('[faiz:] === pull click') - setPluginStyle(LOADING_STYLE) - hidePopup() - await pull(false) - checkStatus() + pull: debounce(async function () { + console.log("[faiz:] === pull click"); + setPluginStyle(LOADING_STYLE); + hidePopup(); + await pull(false); + checkStatus(); }), - pullRebase: debounce(async function() { - console.log('[faiz:] === pullRebase click') - setPluginStyle(LOADING_STYLE) - hidePopup() - await pullRebase() - checkStatus() + pullRebase: debounce(async function () { + console.log("[faiz:] === pullRebase click"); + setPluginStyle(LOADING_STYLE); + hidePopup(); + await pullRebase(); + checkStatus(); }), - checkout: debounce(async function() { - console.log('[faiz:] === checkout click') - hidePopup() - checkout() + checkout: debounce(async function () { + console.log("[faiz:] === checkout click"); + hidePopup(); + checkout(); }), commit: debounce(async function () { - hidePopup() - commit(true, `[logseq-plugin-git:commit] ${new Date().toISOString()}`) + hidePopup(); + commit(true, `[logseq-plugin-git:commit] ${new Date().toISOString()}`); }), push: debounce(async function () { - setPluginStyle(LOADING_STYLE) - hidePopup() - await push() - checkStatus() + setPluginStyle(LOADING_STYLE); + hidePopup(); + await push(); + checkStatus(); }), commitAndPush: debounce(async function () { - setPluginStyle(LOADING_STYLE) - hidePopup() - const res = await commit(true, `[logseq-plugin-git:commit] ${new Date().toISOString()}`) - if (res.exitCode === 0) await push(true) - checkStatus() + setPluginStyle(LOADING_STYLE); + hidePopup(); + const res = await commit( + true, + `[logseq-plugin-git:commit] ${new Date().toISOString()}` + ); + if (res.exitCode === 0) await push(true); + checkStatus(); }), - log: debounce(async function() { - console.log('[faiz:] === log click') - const res = await log(false) - logseq.UI.showMsg(res?.stdout, 'success', { timeout: 0 }) - hidePopup() + log: debounce(async function () { + console.log("[faiz:] === log click"); + const res = await log(false); + logseq.UI.showMsg(res?.stdout, "success", { timeout: 0 }); + hidePopup(); }), - showPopup: debounce(async function() { - console.log('[faiz:] === showPopup click') - showPopup() + showPopup: debounce(async function () { + console.log("[faiz:] === showPopup click"); + showPopup(); }), - hidePopup: debounce(function() { - console.log('[faiz:] === hidePopup click') - hidePopup() + hidePopup: debounce(function () { + console.log("[faiz:] === hidePopup click"); + hidePopup(); }), - } + }; - logseq.provideModel(operations) + logseq.provideModel(operations); - logseq.App.registerUIItem('toolbar', { - key: 'git', - template: '
', - }) - logseq.useSettingsSchema(SETTINGS_SCHEMA) + logseq.App.registerUIItem("toolbar", { + key: "git", + template: + '', + }); + logseq.useSettingsSchema(SETTINGS_SCHEMA); setTimeout(() => { - const buttons = (logseq.settings?.buttons as string[])?.map(title => BUTTONS.find(b => b.title === title)) - if (buttons?.length) { - logseq.provideUI({ - key: 'git-popup', - path: '#plugin-git-content-wrapper', - template: ` - + const buttons = (logseq.settings?.buttons as string[]) + ?.map((title) => BUTTONS.find((b) => b.title === title)) + .filter(Boolean); + if (top && buttons?.length) { + const parser = new DOMParser(); + const doc = parser.parseFromString( + ` +