Skip to content

Commit

Permalink
Feat/plugin marketplace (logseq#2766)
Browse files Browse the repository at this point in the history
* Squashed commit of the following:

commit ea9af27
Author: Tienson Qin <[email protected]>
Date:   Fri Aug 27 00:23:24 2021 +0800

    feat: type c to git commit

    also, fixed an issue that backspace can delete selected blocks
    when there's a dialog.

commit 78e24f7
Author: Tienson Qin <[email protected]>
Date:   Fri Aug 27 00:01:21 2021 +0800

    fix: add patch parser worker to yarn watch

commit 7f6e777
Author: Tienson Qin <[email protected]>
Date:   Thu Aug 26 23:57:46 2021 +0800

    fix: add several shortcuts to the Others category

commit 509697b
Author: Tienson Qin <[email protected]>
Date:   Thu Aug 26 23:55:40 2021 +0800

    fix: git username and email configuration

* Squashed commit of the following:

commit 401d85b
Author: Peng Xiao <[email protected]>
Date:   Fri Aug 27 11:10:32 2021 +0800

    feat: add protobuf mode

commit dc1e9fd
Author: Tienson Qin <[email protected]>
Date:   Fri Aug 27 13:33:47 2021 +0800

    chore: replace : with comma for git path

    ':' is a reserved character on Windows

commit ea9af27
Author: Tienson Qin <[email protected]>
Date:   Fri Aug 27 00:23:24 2021 +0800

    feat: type c to git commit

    also, fixed an issue that backspace can delete selected blocks
    when there's a dialog.

commit 78e24f7
Author: Tienson Qin <[email protected]>
Date:   Fri Aug 27 00:01:21 2021 +0800

    fix: add patch parser worker to yarn watch

commit 7f6e777
Author: Tienson Qin <[email protected]>
Date:   Thu Aug 26 23:57:46 2021 +0800

    fix: add several shortcuts to the Others category

commit 509697b
Author: Tienson Qin <[email protected]>
Date:   Thu Aug 26 23:55:40 2021 +0800

    fix: git username and email configuration

* feat(plugin): ui of marketplace plugins list

* improve(plugin): support reload

* improve(plugin): installation from marketplace

* fix conflicts

* improve(plugin): installation from github public repo

* chore: remove unwanted dependency

* chore: remove console

* improve(plugin): add shortcuts

* ui(plugin): polish LOADING indicator

* improve(plugin): support up-to-date of marketplace plugin

* fix: remove debug option

* improve(plugin): better interaction of themes picker

* improve(plugin): better experience when installing theme from marketplace

* fix(plugin): downloads label of marketplace plugin

* improve(plugin): update package name field

* improve(plugin): change marketplace packages repo to `logseq/marketplace`

* fix(plugin): plugin title when updating notification

* fix: conflicts

* enhance(plugin): i18n related marketplace & lifecycle of plugin installation

* improve(plugin): handle offline situation

* ui(plugin): header plugin icons container

* fix(ui): add class identity for journal page with date page name

* improve(plugin): remote readme for marketplace plugin

* enhance(plugin): polish plugin card

* chore(plugin): build libs core

* Squashed commit of the following:

commit 751db48
Author: Tienson Qin <[email protected]>
Date:   Tue Sep 7 16:58:25 2021 +0800

    enhance: log git errors

commit c2dbbc7
Author: Tienson Qin <[email protected]>
Date:   Tue Sep 7 16:27:00 2021 +0800

    enhance: display refresh status

commit f734b6d
Author: Tienson Qin <[email protected]>
Date:   Tue Sep 7 16:03:57 2021 +0800

    fix: .git doesn't work well with third-party cloud services

commit 7e44d81
Author: Tienson Qin <[email protected]>
Date:   Tue Sep 7 13:52:38 2021 +0800

    fix: git init into the current graph folder

    instead of a separate git directory because .gitdir might has
    different paths on multiple devices, another reason is that the graph
    might have different histories considering the .git directory is not
    synced.

commit b86a801
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 23:23:27 2021 +0800

    enhance: don't show diff if there's only blank changes

commit 0b55d11
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 22:39:06 2021 +0800

    fix: save the previous content in Logseq first and commit it

    to avoid overwritten when syncing with iCloud/Dropbox/syncthing.

commit e0baf4b
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 22:18:45 2021 +0800

    fix: close file watcher when exit the app

commit 10e7a9f
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 21:05:38 2021 +0800

    fix: disable cut selections in the query result block

commit 90c2bd7
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 18:42:17 2021 +0800

    fix: terminate parser and persist dbs when reloading the app (electron)

commit 571c81a
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 17:57:33 2021 +0800

    enhance: add sync from local files (the old refresh way)

commit a16e5c9
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 17:23:57 2021 +0800

    fix: Dragging blocks to update notes does not synchronize updates to
    the notes file in real time.

    close logseq#2744

commit 6897a22
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 16:43:30 2021 +0800

    fix: disable page/block auto-complete once the cursor went outside

commit feb4404
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 13:28:47 2021 +0800

    fix: wrong page metadata saved for another graph

commit b963321
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 13:08:28 2021 +0800

    enhance: catch errors when app quits

commit 1ee0c24
Author: Jiang Hailong <[email protected]>
Date:   Wed Sep 1 20:54:13 2021 +0800

    FIX: Linked reference is not refresh after file altering logseq#2694

commit 0550c8a
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 12:25:39 2021 +0800

    fix: display logbook for scheduled tasks

commit 2a5f0ce
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 12:21:19 2021 +0800

    fix: spent hours for logbook

commit 1f2c9e4
Author: leizhe <[email protected]>
Date:   Sat Sep 4 12:59:09 2021 +0900

    fix(timestamp): remove old SCHEDULED/DEADLINE timestamp

    When using `date-picker` to update the SCHEDULED/DEADLINE timestamp by
    clicking an existing one, logseq will add a new timestamp instead of
    updating the old one. This patch fixs this issue.

commit cb23b96
Author: leizhe <[email protected]>
Date:   Sat Sep 4 11:36:34 2021 +0900

    fix(repeat): more consistent with orgmode style

    Ref: https://orgmode.org/manual/Tracking-your-habits.html

commit 229c7f2
Author: leizhe <[email protected]>
Date:   Sat Sep 4 15:11:07 2021 +0900

    enhance(property): remove empty properties drawer

commit a76df9c
Author: leizhe <[email protected]>
Date:   Sat Sep 4 10:27:30 2021 +0900

    fix(clock): duplicate clock-in log twice

    1. `set-marker` will not log time anymore. The time logging is moved
    to `with-timetracking`
    2. Concat `logbook` only if `new-clocks` is nil, which fixs the
    duplication of clock-in log.

commit c79e9f9
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 12:04:16 2021 +0800

    code: cleanup

commit 9ec85db
Author: DarshanSudhakar <$K3Ug1i&>
Date:   Mon Sep 6 08:32:07 2021 +0530

    Fixing typo  for the tooltip 'Block reference'

commit eec6778
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 11:49:58 2021 +0800

    enhance: page history support reverting back

commit 7273112
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 11:23:31 2021 +0800

    git: revert back

commit cd853b5
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 10:39:08 2021 +0800

    git: should compare ignored-files with disk content

commit a84dfb5
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 10:31:16 2021 +0800

    git: add ignore-files to avoid repeated notifications

commit 86577e7
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 10:07:39 2021 +0800

    fix: ignore permission denied error when git add all

commit 8dc0ca9
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 09:54:03 2021 +0800

    fix: run git config core.safecrlf false on windows

commit 9edaae5
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 09:20:06 2021 +0800

    refactor: extract file ops

commit f12f58d
Author: tiagodevezas <[email protected]>
Date:   Fri Sep 3 23:25:07 2021 +0100

    fix typos

commit 9e82f01
Author: tiagodevezas <[email protected]>
Date:   Fri Sep 3 21:32:03 2021 +0100

    Translate shortcuts to Portuguese (pt-PT)

commit 9a2c17b
Author: tiagodevezas <[email protected]>
Date:   Fri Sep 3 20:58:33 2021 +0100

    Translate new settings to pt-PT

commit c05034c
Author: Sebastian Bensusan <[email protected]>
Date:   Sat Sep 4 07:57:07 2021 -0700

    feat(calc): Understand percentages

commit bfe6a5d
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 6 08:46:30 2021 +0800

    enhance: commit the content in logseq when detecting any disk changes

* improve(plugin): add install plugin api

* fix(plugin): protected plugin installation api

* improve(plugin): tweak readme display for local

* fix: conflicts

* fix(plugin): get block option with include children

* improve(plugin): copy more marketplace manifest fields to plugin

* fix: conflicts

* improve(plugin): shortcut for copying plugin id

* Squashed commit of the following:

commit e51ea54
Author: Tienson Qin <[email protected]>
Date:   Mon Sep 13 10:40:25 2021 +0800

    fix: change ack timeout

* fix(plugin): non blank icon string

* fix: conflicts

* fix: e name

* fix: remove debug from state

* chore(plugin): bump libs minor version

Co-authored-by: Tienson Qin <[email protected]>
  • Loading branch information
xyhp915 and tiensonqin authored Sep 13, 2021
1 parent 790ba85 commit 18b7a78
Show file tree
Hide file tree
Showing 36 changed files with 8,321 additions and 380 deletions.
2 changes: 1 addition & 1 deletion libs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@logseq/libs",
"version": "0.0.1-alpha.27",
"version": "0.0.1-alpha.29",
"description": "Logseq SDK libraries",
"main": "dist/lsplugin.user.js",
"typings": "index.d.ts",
Expand Down
8 changes: 6 additions & 2 deletions libs/src/LSPlugin.caller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,18 @@ class LSPluginCaller extends EventEmitter {
async _setupIframeSandbox () {
const cnt = document.body
const pl = this._pluginLocal!
const id = pl.id
const url = new URL(pl.options.entry!)

url.searchParams
.set(`__v__`, IS_DEV ? Date.now().toString() : pl.options.version)

// clear zombie sandbox
const zb = cnt.querySelector(`#${id}`)
if (zb) zb.parentElement.removeChild(zb)

const pt = new Postmate({
container: cnt, url: url.href,
id, container: cnt, url: url.href,
classListArray: ['lsp-iframe-sandbox'],
model: { baseInfo: JSON.parse(JSON.stringify(pl.toJSON())) }
})
Expand All @@ -217,7 +222,6 @@ class LSPluginCaller extends EventEmitter {
this._connected = true
this.emit('connected')

refChild.frame.setAttribute('id', pl.id)
refChild.on(LSPMSGFn(pl.id), ({ type, payload }: any) => {
debug(`[call from plugin] `, type, payload)

Expand Down
83 changes: 61 additions & 22 deletions libs/src/LSPlugin.core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ type PluginLocalOptions = {
mode: 'shadow' | 'iframe'
settings?: PluginSettings
logger?: PluginLogger
effect?: boolean

[key: string]: any
}
Expand Down Expand Up @@ -357,11 +358,10 @@ class PluginLocal

async _setupUserSettings () {
const { _options } = this
const key = _options.name.replace(/[^a-z0-9]/gi, '_').toLowerCase() + '_' + this.id
const logger = _options.logger = new PluginLogger('Loader')

try {
const [userSettingsFilePath, userSettings] = await invokeHostExportedApi('load_plugin_user_settings', key)
const [userSettingsFilePath, userSettings] = await invokeHostExportedApi('load_plugin_user_settings', this.id)
this._dotSettingsFile = userSettingsFilePath

const settings = _options.settings = new PluginSettings(userSettings)
Expand All @@ -381,7 +381,7 @@ class PluginLocal
}

if (a) {
invokeHostExportedApi(`save_plugin_user_settings`, key, a)
invokeHostExportedApi(`save_plugin_user_settings`, this.id, a)
}
})
} catch (e) {
Expand All @@ -399,13 +399,14 @@ class PluginLocal
}

_resolveResourceFullUrl (filePath: string, localRoot?: string) {
if (!filePath?.trim()) return
localRoot = localRoot || this._localRoot
const reg = /^(http|file)/
if (!reg.test(filePath)) {
const url = path.join(localRoot, filePath)
filePath = reg.test(url) ? url : (PROTOCOL_FILE + url)
}
return this.isInstalledInDotRoot ?
return (!this.options.effect && this.isInstalledInDotRoot) ?
convertToLSPResource(filePath, this.dotPluginsRoot) : filePath
}

Expand All @@ -430,7 +431,9 @@ class PluginLocal
}

// Pick legal attrs
['name', 'author', 'repository', 'version', 'description'].forEach(k => {
['name', 'author', 'repository', 'version',
'description', 'repo', 'title', 'effect'
].forEach(k => {
this._options[k] = pkg[k]
})

Expand All @@ -447,21 +450,26 @@ class PluginLocal
}
}

const title = logseq.title || pkg.title
const icon = logseq.icon || pkg.icon

if (icon) {
this._options.icon = this._resolveResourceFullUrl(icon)
}
this._options.title = title
this._options.icon = icon &&
this._resolveResourceFullUrl(icon)

// TODO: strategy for Logseq plugins center
if (logseq.id) {
this._id = logseq.id
if (this.isInstalledInDotRoot) {
this._id = path.basename(localRoot)
} else {
logseq.id = this.id
try {
await invokeHostExportedApi('save_plugin_config', url, { ...pkg, logseq })
} catch (e) {
debug('[save plugin ID Error] ', e)
if (logseq.id) {
this._id = logseq.id
} else {
logseq.id = this.id
try {
await invokeHostExportedApi('save_plugin_config', url, { ...pkg, logseq })
} catch (e) {
debug('[save plugin ID Error] ', e)
}
}
}

Expand Down Expand Up @@ -609,7 +617,13 @@ class PluginLocal
}

async reload () {
debug('TODO: reload plugin', this.id)
if (this.pending) {
return
}

await this.unload()
await this.load()
this._ctx.emit('reloaded', this)
}

/**
Expand All @@ -624,7 +638,7 @@ class PluginLocal
await this.unload()

if (this.isInstalledInDotRoot) {
debug('TODO: remove plugin local files from user home root :)')
this._ctx.emit('unlink-plugin', this.id)
}

return
Expand All @@ -648,6 +662,7 @@ class PluginLocal
this.emit('unloaded')
} catch (e) {
debug('[plugin unload Error]', e)
return false
} finally {
this._status = PluginLocalLoadStatus.UNLOADED
}
Expand Down Expand Up @@ -773,7 +788,7 @@ class PluginLocal
*/
class LSPluginCore
extends EventEmitter<'beforeenable' | 'enabled' | 'beforedisable' | 'disabled' | 'registered' | 'error' | 'unregistered' |
'theme-changed' | 'theme-selected' | 'settings-changed'>
'theme-changed' | 'theme-selected' | 'settings-changed' | 'unlink-plugin' | 'reloaded'>
implements ILSPluginThemeManager {

private _isRegistering = false
Expand All @@ -782,6 +797,7 @@ class LSPluginCore
private _userPreferences: Partial<UserPreferences> = {}
private _registeredThemes = new Map<PluginLocalIdentity, Array<ThemeOptions>>()
private _registeredPlugins = new Map<PluginLocalIdentity, PluginLocal>()
private _currentTheme: { dis: () => void, pid: PluginLocalIdentity, opt: ThemeOptions }

/**
* @param _options
Expand Down Expand Up @@ -933,8 +949,12 @@ class LSPluginCore
}

for (const identity of plugins) {
const p = this.ensurePlugin(identity)
await p.reload()
try {
const p = this.ensurePlugin(identity)
await p.reload()
} catch (e) {
debug(e)
}
}
}

Expand Down Expand Up @@ -1065,9 +1085,22 @@ class LSPluginCore
}

async selectTheme (opt?: ThemeOptions, effect = true): Promise<void> {
setupInjectedTheme(opt?.url)
// clear current
if (this._currentTheme) {
this._currentTheme.dis?.()
}

const disInjectedTheme = setupInjectedTheme(opt?.url)
this.emit('theme-selected', opt)
effect && this.saveUserPreferences({ theme: opt })
effect && await this.saveUserPreferences({ theme: opt?.url ? opt : null })
if (opt?.url) {
this._currentTheme = {
dis: () => {
disInjectedTheme()
effect && this.saveUserPreferences({ theme: null })
}, opt, pid: opt.pid
}
}
}

async unregisterTheme (id: PluginLocalIdentity): Promise<void> {
Expand All @@ -1076,6 +1109,12 @@ class LSPluginCore
if (!this._registeredThemes.has(id)) return
this._registeredThemes.delete(id)
this.emit('theme-changed', this.themes, { id })
if (this._currentTheme?.pid == id) {
this._currentTheme.dis?.()
this._currentTheme = null
// reset current theme
this.emit('theme-selected', null)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions libs/src/LSPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export type UIOptions = UIPathOptions | UISlotOptions

export interface LSPluginPkgConfig {
id: PluginLocalIdentity
title: string
mode: 'shadow' | 'iframe'
themes: Array<ThemeOptions>
icon: string
Expand Down
7 changes: 6 additions & 1 deletion libs/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export function invokeHostExportedApi (
method: string,
...args: Array<any>
) {
method = method?.replace(/^[_$]+/, '')
const method1 = snakeCase(method)

// @ts-ignore
Expand Down Expand Up @@ -335,7 +336,11 @@ export function setupInjectedTheme (url?: string) {
document.head.appendChild(link)

return (injectedThemeEffect = () => {
document.head.removeChild(link)
try {
document.head.removeChild(link)
} catch (e) {
console.error(e)
}
injectedThemeEffect = null
})
}
4 changes: 3 additions & 1 deletion libs/src/postmate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export class ChildAPI {
export type PostMateOptions = {
container: HTMLElement
url: string
id?: string
classListArray?: Array<string>
name?: string
model?: any
Expand Down Expand Up @@ -281,7 +282,8 @@ export class Postmate {
this.url = opts.url
this.parent = window
this.frame = document.createElement('iframe')
this.frame.name = opts.name || ''
if (opts.id) this.frame.id = opts.id
if (opts.name) this.frame.name = opts.name
this.frame.classList.add.apply(this.frame.classList, opts.classListArray || [])
this.container.appendChild(this.frame)
this.child = this.frame.contentWindow
Expand Down
6,916 changes: 6,913 additions & 3 deletions resources/js/lsplugin.core.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions resources/js/marked.min.js

Large diffs are not rendered by default.

38 changes: 27 additions & 11 deletions resources/js/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { ipcRenderer, contextBridge, shell, clipboard, webFrame } = require('elec
const IS_MAC = process.platform === 'darwin'
const IS_WIN32 = process.platform === 'win32'

function getFilePathFromClipboard() {
function getFilePathFromClipboard () {
if (IS_WIN32) {
const rawFilePath = clipboard.read('FileNameW')
return rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), '')
Expand All @@ -16,7 +16,7 @@ function getFilePathFromClipboard() {
}
}

function isClipboardHasImage() {
function isClipboardHasImage () {
return !clipboard.readImage().isEmpty()
}

Expand All @@ -25,36 +25,52 @@ contextBridge.exposeInMainWorld('apis', {
return await ipcRenderer.invoke('main', arg)
},

addListener: ipcRenderer.on.bind(ipcRenderer),
removeListener: ipcRenderer.removeListener.bind(ipcRenderer),
removeAllListeners: ipcRenderer.removeAllListeners.bind(ipcRenderer),

on: (channel, callback) => {
const newCallback = (_, data) => callback(data)
ipcRenderer.on(channel, newCallback)
},

off: (channel, callback) => {
if (!callback) {
ipcRenderer.removeAllListeners(channel)
} else {
ipcRenderer.removeListener(channel, callback)
}
},

once: (channel, callback) => {
ipcRenderer.on(channel, callback)
},

checkForUpdates: async (...args) => {
await ipcRenderer.invoke('check-for-updates', ...args)
},

setUpdatesCallback(cb) {
setUpdatesCallback (cb) {
if (typeof cb !== 'function') return

const channel = 'updates-callback'
ipcRenderer.removeAllListeners(channel)
ipcRenderer.on(channel, cb)
},

installUpdatesAndQuitApp() {
installUpdatesAndQuitApp () {
ipcRenderer.invoke('install-updates', true)
},

async openExternal(url, options) {
async openExternal (url, options) {
await shell.openExternal(url, options)
},

async openPath(path) {
async openPath (path) {
await shell.openPath(path)
},

showItemInFolder(fullpath) {
showItemInFolder (fullpath) {
if (IS_WIN32) {
shell.openPath(path.dirname(fullpath))
} else {
Expand All @@ -67,7 +83,7 @@ contextBridge.exposeInMainWorld('apis', {
*
* @param {string} html html file with embedded state
*/
exportPublishAssets(html, customCSSPath, repoPath, assetFilenames) {
exportPublishAssets (html, customCSSPath, repoPath, assetFilenames) {
ipcRenderer.invoke(
'export-publish-assets',
html,
Expand All @@ -85,7 +101,7 @@ contextBridge.exposeInMainWorld('apis', {
* @param from?
* @returns {Promise<void>}
*/
async copyFileToAssets(repoPathRoot, to, from) {
async copyFileToAssets (repoPathRoot, to, from) {
if (from && fs.statSync(from).isDirectory()) {
throw new Error('not support copy directory')
}
Expand Down Expand Up @@ -120,7 +136,7 @@ contextBridge.exposeInMainWorld('apis', {
}
},

toggleMaxOrMinActiveWindow(isToggleMin = false) {
toggleMaxOrMinActiveWindow (isToggleMin = false) {
ipcRenderer.invoke('toggle-max-or-min-active-win', isToggleMin)
},

Expand All @@ -130,7 +146,7 @@ contextBridge.exposeInMainWorld('apis', {
* @param args
* @private
*/
async _callApplication(type, ...args) {
async _callApplication (type, ...args) {
return await ipcRenderer.invoke('call-application', type, ...args)
},

Expand Down
Loading

0 comments on commit 18b7a78

Please sign in to comment.