-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
2,837 additions
and
578 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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"$schema": "https://ui.shadcn.com/schema.json", | ||
"style": "default", | ||
"rsc": false, | ||
"tsx": true, | ||
"tailwind": { | ||
"config": "tailwind.config.js", | ||
"css": "src/webview/styles.css", | ||
"baseColor": "slate", | ||
"cssVariables": true, | ||
"prefix": "" | ||
}, | ||
"aliases": { | ||
"components": "@/components", | ||
"utils": "@/lib/utils" | ||
} | ||
} |
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,6 @@ | ||
export default { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
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 |
---|---|---|
@@ -1,43 +1,69 @@ | ||
import joplin from 'joplin-plugin-api' | ||
import { IProtocol, onMessage } from './message' | ||
import joplin, { MenuItemLocation, ViewHandle } from 'joplin-plugin-api' | ||
import { IProtocol } from './message' | ||
import { defineExtensionMessaging } from 'jpl-vite/messaging' | ||
import { joplinDataApi } from 'joplin-api' | ||
import { get } from 'lodash-es' | ||
|
||
joplin.plugins.register({ | ||
onStart: async function () { | ||
await registerSettings() | ||
// 实现这个命令的功能,生成 markdown 文件并使用 git 推送到远端仓库 | ||
await registerCommands() | ||
await registerMenus() | ||
}, | ||
}) | ||
|
||
async function registerCommands() { | ||
const dataApi = joplinDataApi({ type: 'plugin' }) | ||
|
||
let handler: ViewHandle | ||
await joplin.commands.register({ | ||
name: 'webviewTest', | ||
label: 'Webview Test', | ||
name: 'joplin-batch.visible', | ||
label: 'Joplin Batch', | ||
async execute() { | ||
const dialogs = joplin.views.dialogs | ||
const handler = await dialogs.create(new Date().toISOString()) | ||
await dialogs.addScript(handler, '/webview/index.js') | ||
await dialogs.addScript(handler, '/webview/index.css') | ||
await dialogs.setButtons(handler, [ | ||
{ | ||
id: 'close', | ||
title: 'Close', | ||
}, | ||
]) | ||
const { onMessage, sendMessage } = defineExtensionMessaging<IProtocol>(handler) | ||
const panels = joplin.views.panels | ||
if (handler) { | ||
const isVisible = await panels.visible(handler) | ||
await panels.show(handler, !isVisible) | ||
return | ||
} | ||
handler = await panels.create('Batch Utils') | ||
await panels.addScript(handler, '/webview/index.js') | ||
await panels.addScript(handler, '/webview/style.css') | ||
const { onMessage } = defineExtensionMessaging<IProtocol>(handler) | ||
let last = 0 | ||
onMessage('add', (a, b) => { | ||
last = a + b | ||
return last | ||
}) | ||
onMessage('value', () => last) | ||
await dialogs.open(handler) | ||
onMessage('invokeDataApi', (method, ...args) => { | ||
const f = deepGet(dataApi, method) | ||
if (!f) { | ||
throw new Error(`Method ${method} not found`) | ||
} | ||
return f(...args) | ||
}) | ||
await panels.visible(handler) | ||
}, | ||
}) | ||
} | ||
|
||
async function registerMenus() {} | ||
async function registerMenus() { | ||
await joplin.views.menuItems.create('joplin-batch.visible', 'joplin-batch.visible', MenuItemLocation.Tools) | ||
} | ||
|
||
function deepGet(obj: any, path: string): Function | undefined { | ||
let result = get(obj, path) | ||
|
||
async function registerSettings() {} | ||
// 如果结果是一个函数,我们需要绑定 this | ||
if (typeof result === 'function') { | ||
// 获取父对象 | ||
const parentPath = path.split('.').slice(0, -1).join('.') | ||
const parent = parentPath ? get(obj, parentPath) : obj | ||
|
||
// 绑定函数到父对象 | ||
result = result.bind(parent) | ||
} | ||
|
||
return result | ||
} |
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 |
---|---|---|
@@ -1,23 +1,119 @@ | ||
import { useSignal } from '@preact/signals' | ||
import { useInterval } from 'react-use' | ||
import { sendMessage } from '../message' | ||
import { Button } from './components/ui/button' | ||
import { Link, RouteConfig, RouterView, useLocation, useMatch } from '@liuli-util/react-router' | ||
import { DemoView } from './views/DemoView' | ||
import { CheckUnusedResourceView } from './views/UnusedResourceView' | ||
import { SettingsView } from './views/SettingsView' | ||
import { Menu } from 'lucide-react' | ||
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from './components/ui/sheet' | ||
import { useDeepSignal } from 'deepsignal/react' | ||
import { useEffect } from 'react' | ||
import { ReplaceAllView } from './views/ReplaceAllView' | ||
import { Separator } from './components/ui/separator' | ||
|
||
export default function App() { | ||
const count = useSignal(new Date()) | ||
|
||
useInterval(() => { | ||
count.value = new Date() | ||
}, 100) | ||
function HomeView() { | ||
return <div>home</div> | ||
} | ||
|
||
async function onPostMessage() { | ||
console.log(await sendMessage('add', 1, 2)) | ||
type MenuConfig = RouteConfig & { | ||
meta?: { | ||
title: string | ||
} | ||
} | ||
export const routeList: MenuConfig[] = [ | ||
{ | ||
path: '/', | ||
component: CheckUnusedResourceView, | ||
meta: { | ||
title: 'Unused Resources', | ||
}, | ||
}, | ||
{ | ||
path: '/replace-all', | ||
component: ReplaceAllView, | ||
meta: { | ||
title: 'Replace All', | ||
}, | ||
}, | ||
{ | ||
path: '/settings', | ||
component: SettingsView, | ||
meta: { | ||
title: 'Settings', | ||
}, | ||
}, | ||
// { | ||
// path: '/demo', | ||
// component: DemoView, | ||
// meta: { | ||
// title: 'Demo', | ||
// }, | ||
// }, | ||
] | ||
|
||
function MenuItem(route: Pick<MenuConfig, 'path' | 'meta'>) { | ||
const loc = useLocation() | ||
return ( | ||
<Link to={route.path} key={route.path}> | ||
<Button variant={loc.pathname === route.path ? 'secondary' : 'ghost'} className="w-full justify-start"> | ||
{route.meta?.title} | ||
</Button> | ||
</Link> | ||
) | ||
} | ||
|
||
function Sidebar() { | ||
const loc = useLocation() | ||
return ( | ||
<aside className="space-y-1"> | ||
{routeList | ||
.filter((it) => it.meta) | ||
.map((route) => ( | ||
<Link to={route.path} key={route.path}> | ||
<Button variant={loc.pathname === route.path ? 'secondary' : 'ghost'} className="w-full justify-start"> | ||
{route.meta!.title} | ||
</Button> | ||
</Link> | ||
))} | ||
</aside> | ||
) | ||
} | ||
|
||
export default function App() { | ||
const isOpen = useDeepSignal({ | ||
value: false, | ||
}) | ||
useEffect(() => { | ||
isOpen.value = false | ||
}, [useLocation()]) | ||
return ( | ||
<div> | ||
<h1>Joplin Batch</h1> | ||
<div>{count.value.toJSON()}</div> | ||
<button onClick={onPostMessage}>postMessage</button> | ||
<div className="min-h-screen flex flex-col"> | ||
<header className="border-b flex justify-between items-center"> | ||
<div className="flex items-center"> | ||
<Sheet open={isOpen.value} onOpenChange={(value) => (isOpen.value = value)}> | ||
<SheetTrigger asChild> | ||
<Button variant="ghost" size="icon" onClick={() => (isOpen.value = !isOpen.value)}> | ||
<Menu className={'h-6 w-6'} /> | ||
</Button> | ||
</SheetTrigger> | ||
<SheetContent side={'left'}> | ||
<SheetHeader> | ||
<SheetTitle> | ||
<Link to={'/'} className={'px-4 block'}> | ||
Joplin Batch | ||
</Link> | ||
</SheetTitle> | ||
<SheetDescription></SheetDescription> | ||
</SheetHeader> | ||
<Sidebar /> | ||
</SheetContent> | ||
</Sheet> | ||
</div> | ||
</header> | ||
<div className="flex-grow"> | ||
<div className="h-full px-4 py-6 lg:px-8"> | ||
<RouterView /> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
Oops, something went wrong.