-
-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui/plugins): support dynamic loading of ui plug-in scripts
- Loading branch information
Showing
12 changed files
with
162 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -168,3 +168,4 @@ frontend: | |
scrollable: false | ||
reqTimeout: 15000 | ||
versionCheck: true | ||
pluginURLs: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -329,3 +329,5 @@ frontend: | |
reqTimeout: 15000 | ||
# Version check | ||
versionCheck: true | ||
# Plugins | ||
pluginURLs: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -336,3 +336,5 @@ frontend: | |
reqTimeout: 15000 | ||
# 版本检测 | ||
versionCheck: true | ||
# 插件 | ||
pluginURLs: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import type { ArtalkConfig, ArtalkPlugin, ContextApi } from '@/types' | ||
import { handleConfFormServer } from '@/config' | ||
import { showErrorDialog } from '@/components/error-dialog' | ||
import { DefaultPlugins } from './plugins' | ||
|
||
/** | ||
* Global Plugins for all Artalk instances | ||
*/ | ||
export const GlobalPlugins: ArtalkPlugin[] = [ ...DefaultPlugins ] | ||
|
||
export async function load(ctx: ContextApi) { | ||
const loadedPlugins: ArtalkPlugin[] = [] | ||
const loadPlugins = (plugins: ArtalkPlugin[]) => { | ||
plugins.forEach((plugin) => { | ||
if (typeof plugin === 'function' && !loadedPlugins.includes(plugin)) { | ||
plugin(ctx) | ||
loadedPlugins.push(plugin) | ||
} | ||
}) | ||
} | ||
|
||
// Load local plugins | ||
loadPlugins(GlobalPlugins) | ||
|
||
// Get conf from server | ||
const { data } = await ctx.getApi().conf.conf().catch((err) => { | ||
onLoadErr(ctx, err) | ||
throw err | ||
}) | ||
|
||
// Initial config | ||
let conf: Partial<ArtalkConfig> = { | ||
apiVersion: data.version?.version, // version info | ||
} | ||
|
||
// Reference conf from backend | ||
if (ctx.conf.useBackendConf) { | ||
if (!data.frontend_conf) throw new Error('The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled') | ||
conf = { ...conf, ...handleConfFormServer(data.frontend_conf) } | ||
} | ||
|
||
// Apply conf modifier | ||
ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf) | ||
|
||
// Dynamically load network plugins | ||
conf.pluginURLs && await loadNetworkPlugins(conf.pluginURLs, ctx.conf.server).then((plugins) => { | ||
loadPlugins(plugins) | ||
}).catch((err) => { | ||
console.error('Failed to load plugin', err) | ||
}) | ||
|
||
// After all plugins are loaded | ||
ctx.trigger('created') | ||
|
||
// Apply conf updating | ||
ctx.updateConf(conf) | ||
|
||
// Trigger mounted event | ||
ctx.trigger('mounted') | ||
|
||
// Load comment list | ||
if (!ctx.conf.remoteConfModifier) { // only auto fetch when no remoteConfModifier | ||
ctx.fetch({ offset: 0 }) | ||
} | ||
} | ||
|
||
/** | ||
* Dynamically load plugins from Network | ||
*/ | ||
async function loadNetworkPlugins(scripts: string[], apiBase: string): Promise<ArtalkPlugin[]> { | ||
if (!scripts || !Array.isArray(scripts)) return [] | ||
|
||
const tasks: Promise<void>[] = [] | ||
|
||
scripts.forEach((url) => { | ||
// check url valid | ||
if (!/^(http|https):\/\//.test(url)) | ||
url = `${apiBase.replace(/\/$/, '')}/${url.replace(/^\//, '')}` | ||
|
||
tasks.push(new Promise<void>((resolve, reject) => { | ||
// load artalk-plugin-auth.js | ||
const script = document.createElement('script') | ||
script.src = url | ||
document.head.appendChild(script) | ||
script.onload = () => resolve() | ||
script.onerror = (err) => reject(err) | ||
})) | ||
}) | ||
|
||
await Promise.all(tasks) | ||
|
||
return Object.values(window.ArtalkPlugins || {}) | ||
} | ||
|
||
export function onLoadErr(ctx: ContextApi, err: any) { | ||
let sidebarOpenView = '' | ||
|
||
// if response err_no_site, modify the sidebar open view to create site | ||
if (err.data?.err_no_site) { | ||
const viewLoadParam = { create_name: ctx.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` } | ||
sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}` | ||
} | ||
|
||
showErrorDialog({ | ||
$err: ctx.get('list').$el, | ||
errMsg: err.msg || String(err), | ||
errData: err.data, | ||
retryFn: () => load(ctx), | ||
onOpenSidebar: ctx.get('user').getData().isAdmin ? () => ctx.showSidebar({ | ||
view: sidebarOpenView as any | ||
}) : undefined // only show open sidebar button when user is admin | ||
}) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ArtalkPlugin } from '.' | ||
|
||
export {} | ||
|
||
declare global { | ||
interface Window { | ||
ArtalkPlugins?: { [name: string]: ArtalkPlugin } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters