Action button prototype
This commit is contained in:
parent
3037dbe58a
commit
7e221ce5aa
@ -42,14 +42,14 @@ functions:
|
||||
path: ./page.ts:linkQueryProvider
|
||||
events:
|
||||
- query:link
|
||||
indexItems:
|
||||
path: "./item.ts:indexItems"
|
||||
events:
|
||||
- page:index
|
||||
itemQueryProvider:
|
||||
path: ./item.ts:queryProvider
|
||||
events:
|
||||
- query:item
|
||||
# indexItems:
|
||||
# path: "./item.ts:indexItems"
|
||||
# events:
|
||||
# - page:index
|
||||
# itemQueryProvider:
|
||||
# path: ./item.ts:queryProvider
|
||||
# events:
|
||||
# - query:item
|
||||
deletePage:
|
||||
path: "./page.ts:deletePage"
|
||||
command:
|
||||
@ -67,6 +67,9 @@ functions:
|
||||
name: "Page: Rename"
|
||||
mac: Cmd-Alt-r
|
||||
key: Ctrl-Alt-r
|
||||
button:
|
||||
label: "📝"
|
||||
tooltip: "Rename page"
|
||||
pageComplete:
|
||||
path: "./page.ts:pageComplete"
|
||||
events:
|
||||
@ -99,7 +102,20 @@ functions:
|
||||
path: ./page.ts:parsePageCommand
|
||||
command:
|
||||
name: "Debug: Parse Document"
|
||||
|
||||
insertPageMeta:
|
||||
path: "./page.ts:insertPageMeta"
|
||||
slashCommand:
|
||||
name: meta
|
||||
quickNoteCommand:
|
||||
path: ./template.ts:quickNoteCommand
|
||||
command:
|
||||
name: "Template: Quick Note"
|
||||
key: "Alt-Shift-n"
|
||||
quickTaskCommand:
|
||||
path: ./template.ts:quickTaskCommand
|
||||
command:
|
||||
name: "Template: Quick Task"
|
||||
key: "Alt-Shift-t"
|
||||
instantiateTemplateCommand:
|
||||
path: ./template.ts:instantiateTemplateCommand
|
||||
command:
|
||||
|
@ -9,8 +9,11 @@ import {
|
||||
import {
|
||||
flashNotification,
|
||||
getCurrentPage,
|
||||
getCursor,
|
||||
getText,
|
||||
insertAtCursor,
|
||||
matchBefore,
|
||||
moveCursor,
|
||||
navigate,
|
||||
prompt,
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall/editor";
|
||||
@ -247,3 +250,9 @@ export async function parsePageCommand() {
|
||||
export async function parsePage(text: string) {
|
||||
console.log("AST", JSON.stringify(await parseMarkdown(text), null, 2));
|
||||
}
|
||||
|
||||
export async function insertPageMeta() {
|
||||
let cursorPos = await getCursor();
|
||||
await insertAtCursor("```meta\n\n```");
|
||||
await moveCursor(cursorPos + 8);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall/space";
|
||||
import {
|
||||
filterBox,
|
||||
moveCursor,
|
||||
navigate,
|
||||
prompt,
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall/editor";
|
||||
@ -35,7 +36,7 @@ export async function instantiateTemplateCommand() {
|
||||
let { text } = await readPage(selectedTemplate.name);
|
||||
|
||||
let parseTree = await parseMarkdown(text);
|
||||
let additionalPageMeta = extractMeta(parseTree, true);
|
||||
let additionalPageMeta = extractMeta(parseTree, ["name"]);
|
||||
console.log("Page meta", additionalPageMeta);
|
||||
|
||||
let pageName = await prompt("Name of new page", additionalPageMeta.name);
|
||||
@ -47,6 +48,7 @@ export async function instantiateTemplateCommand() {
|
||||
await navigate(pageName);
|
||||
}
|
||||
|
||||
// TODO: This should probably be replaced with handlebards somehow?
|
||||
export function replaceTemplateVars(s: string, pageName: string): string {
|
||||
return s.replaceAll(/\{\{([^\}]+)\}\}/g, (match, v) => {
|
||||
switch (v) {
|
||||
@ -64,3 +66,22 @@ export function replaceTemplateVars(s: string, pageName: string): string {
|
||||
return match;
|
||||
});
|
||||
}
|
||||
|
||||
export async function quickNoteCommand() {
|
||||
let isoDate = new Date().toISOString();
|
||||
let [date, time] = isoDate.split("T");
|
||||
time = time.split(".")[0];
|
||||
let pageName = `📥 ${date} ${time}`;
|
||||
await writePage(pageName, "");
|
||||
await navigate(pageName);
|
||||
}
|
||||
|
||||
export async function quickTaskCommand() {
|
||||
let isoDate = new Date().toISOString();
|
||||
let [date, time] = isoDate.split("T");
|
||||
time = time.split(".")[0];
|
||||
let pageName = `✅ ${date} ${time}`;
|
||||
await writePage(pageName, "* [ ] ");
|
||||
await navigate(pageName);
|
||||
await moveCursor(6);
|
||||
}
|
||||
|
@ -5,6 +5,6 @@ functions:
|
||||
events:
|
||||
- query:gh-events
|
||||
queryIssues:
|
||||
path: ./github.ts:queryIssues
|
||||
path: ./github.ts:queryPulls
|
||||
events:
|
||||
- query:gh-issues
|
||||
- query:gh-pulls
|
||||
|
@ -61,9 +61,13 @@ class GithubApi {
|
||||
);
|
||||
}
|
||||
|
||||
async listIssues(filter: string): Promise<any[]> {
|
||||
async listPulls(
|
||||
repo: string,
|
||||
state: string = "all",
|
||||
sort: string = "updated"
|
||||
): Promise<any[]> {
|
||||
return this.apiCall(
|
||||
`https://api.github.com/issues?q=${encodeURIComponent(filter)}`
|
||||
`https://api.github.com/repos/${repo}/pulls?state=${state}&sort=${sort}&direction=desc&per_page=100`
|
||||
);
|
||||
}
|
||||
|
||||
@ -126,27 +130,40 @@ export async function queryEvents({
|
||||
return applyQuery(query, allEvents.map(mapEvent));
|
||||
}
|
||||
|
||||
export async function queryIssues({
|
||||
function mapPull(pull: any): any {
|
||||
// console.log("Pull", Object.keys(pull));
|
||||
return {
|
||||
...pull,
|
||||
username: pull.user.login,
|
||||
// repo: pull.repo.name,
|
||||
createdAt: pull.created_at.split("T")[0],
|
||||
updatedAt: pull.updated_at.split("T")[0],
|
||||
};
|
||||
}
|
||||
|
||||
export async function queryPulls({
|
||||
query,
|
||||
}: QueryProviderEvent): Promise<any[]> {
|
||||
let api = await GithubApi.fromConfig();
|
||||
let filter = query.filter.find((f) => f.prop === "filter");
|
||||
if (!filter) {
|
||||
throw Error("No 'filter' specified, this is mandatory");
|
||||
let repo = query.filter.find((f) => f.prop === "repo");
|
||||
if (!repo) {
|
||||
throw Error("No 'repo' specified, this is mandatory");
|
||||
}
|
||||
let queries: string[] = [];
|
||||
if (filter.op === "=") {
|
||||
queries = [filter.value];
|
||||
} else if (filter.op === "in") {
|
||||
queries = filter.value;
|
||||
query.filter.splice(query.filter.indexOf(repo), 1);
|
||||
let repos: string[] = [];
|
||||
if (repo.op === "=") {
|
||||
repos = [repo.value];
|
||||
} else if (repo.op === "in") {
|
||||
repos = repo.value;
|
||||
} else {
|
||||
throw new Error(`Unsupported operator ${filter.op}`);
|
||||
throw new Error(`Unsupported operator ${repo.op}`);
|
||||
}
|
||||
let allIssues: any[] = [];
|
||||
for (let issuesList of await Promise.all(
|
||||
queries.map((query) => api.listIssues(query))
|
||||
let allPulls: any[] = [];
|
||||
for (let pullList of await Promise.all(
|
||||
repos.map((repo) => api.listPulls(repo, "all", "updated"))
|
||||
)) {
|
||||
allIssues.push(...issuesList);
|
||||
allPulls.push(...pullList);
|
||||
}
|
||||
return allIssues;
|
||||
allPulls = applyQuery(query, allPulls.map(mapPull));
|
||||
return allPulls;
|
||||
}
|
||||
|
@ -12,10 +12,14 @@ import {
|
||||
ParseTree,
|
||||
replaceNodesMatching,
|
||||
} from "@silverbulletmd/common/tree";
|
||||
import { parse as parseYaml, parseAllDocuments } from "yaml";
|
||||
import {
|
||||
parse as parseYaml,
|
||||
stringify as stringifyYaml,
|
||||
parseAllDocuments,
|
||||
} from "yaml";
|
||||
import type { QueryProviderEvent } from "./engine";
|
||||
import { applyQuery } from "./engine";
|
||||
import { jsonToMDTable, removeQueries } from "./util";
|
||||
import { removeQueries } from "./util";
|
||||
|
||||
export async function indexData({ name, tree }: IndexTreeEvent) {
|
||||
let dataObjects: { key: string; value: Object }[] = [];
|
||||
@ -58,8 +62,11 @@ export async function indexData({ name, tree }: IndexTreeEvent) {
|
||||
await batchSet(name, dataObjects);
|
||||
}
|
||||
|
||||
export function extractMeta(parseTree: ParseTree, remove = false): any {
|
||||
let data = {};
|
||||
export function extractMeta(
|
||||
parseTree: ParseTree,
|
||||
removeKeys: string[] = []
|
||||
): any {
|
||||
let data: any = {};
|
||||
replaceNodesMatching(parseTree, (t) => {
|
||||
if (t.type !== "FencedCode") {
|
||||
return;
|
||||
@ -78,7 +85,14 @@ export function extractMeta(parseTree: ParseTree, remove = false): any {
|
||||
}
|
||||
let codeText = codeTextNode.children![0].text!;
|
||||
data = parseYaml(codeText);
|
||||
return remove ? null : undefined;
|
||||
if (removeKeys.length > 0) {
|
||||
let newData = { ...data };
|
||||
for (let key of removeKeys) {
|
||||
delete newData[key];
|
||||
}
|
||||
codeTextNode.children![0].text = stringifyYaml(newData).trim();
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return data;
|
||||
|
@ -174,6 +174,7 @@ export function FilterList({
|
||||
break;
|
||||
}
|
||||
}}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Notification } from "../types";
|
||||
import { ActionButton, Notification } from "../types";
|
||||
|
||||
function prettyName(s: string | undefined): string {
|
||||
if (!s) {
|
||||
@ -11,6 +11,7 @@ export function TopBar({
|
||||
pageName,
|
||||
unsavedChanges,
|
||||
notifications,
|
||||
actionButtons,
|
||||
onClick,
|
||||
lhs,
|
||||
rhs,
|
||||
@ -18,6 +19,7 @@ export function TopBar({
|
||||
pageName?: string;
|
||||
unsavedChanges: boolean;
|
||||
notifications: Notification[];
|
||||
actionButtons: ActionButton[];
|
||||
onClick: () => void;
|
||||
lhs?: React.ReactNode;
|
||||
rhs?: React.ReactNode;
|
||||
@ -27,24 +29,11 @@ export function TopBar({
|
||||
{lhs}
|
||||
<div className="main">
|
||||
<div className="inner">
|
||||
{/*<span className={`icon ${unsavedChanges ? "unsaved" : "saved"}`}>*/}
|
||||
{/* <FontAwesomeIcon icon={faFileLines} />*/}
|
||||
{/*</span>*/}
|
||||
|
||||
<span
|
||||
className={`current-page ${unsavedChanges ? "unsaved" : "saved"}`}
|
||||
>
|
||||
{prettyName(pageName)}
|
||||
</span>
|
||||
{/*<button*/}
|
||||
{/* onClick={(e) => {*/}
|
||||
{/* // @ts-ignore*/}
|
||||
{/* window.syncer();*/}
|
||||
{/* e.stopPropagation();*/}
|
||||
{/* }}*/}
|
||||
{/*>*/}
|
||||
{/* Sync*/}
|
||||
{/*</button>*/}
|
||||
{notifications.length > 0 && (
|
||||
<div className="status">
|
||||
{notifications.map((notification) => (
|
||||
@ -52,6 +41,20 @@ export function TopBar({
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="actions">
|
||||
{actionButtons.map((actionButton, idx) => (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
actionButton.run();
|
||||
}}
|
||||
title={actionButton.tooltip}
|
||||
>
|
||||
{actionButton.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{rhs}
|
||||
|
@ -99,10 +99,11 @@ export class Editor {
|
||||
// Command hook
|
||||
this.commandHook = new CommandHook();
|
||||
this.commandHook.on({
|
||||
commandsUpdated: (commandMap) => {
|
||||
commandsUpdated: (commandMap, actionButtons) => {
|
||||
this.viewDispatch({
|
||||
type: "update-commands",
|
||||
commands: commandMap,
|
||||
actionButtons: actionButtons,
|
||||
});
|
||||
},
|
||||
});
|
||||
@ -603,6 +604,16 @@ export class Editor {
|
||||
pageName={viewState.currentPage}
|
||||
notifications={viewState.notifications}
|
||||
unsavedChanges={viewState.unsavedChanges}
|
||||
actionButtons={[
|
||||
{
|
||||
label: "⚡️",
|
||||
orderId: 0,
|
||||
run: () => {
|
||||
this.viewDispatch({ type: "show-palette" });
|
||||
},
|
||||
},
|
||||
...viewState.actionButtons,
|
||||
]}
|
||||
onClick={() => {
|
||||
dispatch({ type: "start-navigate" });
|
||||
}}
|
||||
|
100
packages/web/fonts/LICENSE.md
Normal file
100
packages/web/fonts/LICENSE.md
Normal file
@ -0,0 +1,100 @@
|
||||
# iA Writer Typeface
|
||||
|
||||
Copyright © 2018 Information Architects Inc. with Reserved Font Name "iA Writer"
|
||||
|
||||
# Based on IBM Plex Typeface
|
||||
|
||||
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
|
||||
|
||||
# License
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
packages/web/fonts/iAWriterMonoS-Bold.woff2
Normal file
BIN
packages/web/fonts/iAWriterMonoS-Bold.woff2
Normal file
Binary file not shown.
BIN
packages/web/fonts/iAWriterMonoS-BoldItalic.woff2
Normal file
BIN
packages/web/fonts/iAWriterMonoS-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
packages/web/fonts/iAWriterMonoS-Italic.woff2
Normal file
BIN
packages/web/fonts/iAWriterMonoS-Italic.woff2
Normal file
Binary file not shown.
BIN
packages/web/fonts/iAWriterMonoS-Regular.woff2
Normal file
BIN
packages/web/fonts/iAWriterMonoS-Regular.woff2
Normal file
Binary file not shown.
@ -1,6 +1,7 @@
|
||||
import { Hook, Manifest } from "@plugos/plugos/types";
|
||||
import { System } from "@plugos/plugos/system";
|
||||
import { EventEmitter } from "@plugos/plugos/event";
|
||||
import { ActionButton } from "../types";
|
||||
|
||||
export type CommandDef = {
|
||||
name: string;
|
||||
@ -10,6 +11,14 @@ export type CommandDef = {
|
||||
// Bind to keyboard shortcut
|
||||
key?: string;
|
||||
mac?: string;
|
||||
|
||||
// Action button
|
||||
button?: ButtonDef;
|
||||
};
|
||||
|
||||
export type ButtonDef = {
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
};
|
||||
|
||||
export type AppCommand = {
|
||||
@ -22,7 +31,10 @@ export type CommandHookT = {
|
||||
};
|
||||
|
||||
export type CommandHookEvents = {
|
||||
commandsUpdated(commandMap: Map<string, AppCommand>): void;
|
||||
commandsUpdated(
|
||||
commandMap: Map<string, AppCommand>,
|
||||
appButtons: ActionButton[]
|
||||
): void;
|
||||
};
|
||||
|
||||
export class CommandHook
|
||||
@ -30,9 +42,11 @@ export class CommandHook
|
||||
implements Hook<CommandHookT>
|
||||
{
|
||||
editorCommands = new Map<string, AppCommand>();
|
||||
actionButtons: ActionButton[] = [];
|
||||
|
||||
buildAllCommands(system: System<CommandHookT>) {
|
||||
this.editorCommands.clear();
|
||||
this.actionButtons = [];
|
||||
for (let plug of system.loadedPlugs.values()) {
|
||||
for (const [name, functionDef] of Object.entries(
|
||||
plug.manifest!.functions
|
||||
@ -47,9 +61,18 @@ export class CommandHook
|
||||
return plug.invoke(name, []);
|
||||
},
|
||||
});
|
||||
if (cmd.button) {
|
||||
this.actionButtons.push({
|
||||
label: cmd.button.label,
|
||||
tooltip: cmd.button.tooltip,
|
||||
run: () => {
|
||||
return plug.invoke(name, []);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
this.emit("commandsUpdated", this.editorCommands);
|
||||
}
|
||||
this.emit("commandsUpdated", this.editorCommands, this.actionButtons);
|
||||
}
|
||||
|
||||
apply(system: System<CommandHookT>): void {
|
||||
|
@ -67,6 +67,7 @@ export default function reducer(
|
||||
return {
|
||||
...state,
|
||||
commands: action.commands,
|
||||
actionButtons: action.actionButtons,
|
||||
};
|
||||
case "show-notification":
|
||||
return {
|
||||
|
@ -249,7 +249,7 @@
|
||||
color: #989797;
|
||||
background-color: rgba(210, 210, 210, 0.2);
|
||||
border-radius: 5px;
|
||||
font-style: italic;
|
||||
// font-style: italic;
|
||||
font-size: 75%;
|
||||
line-height: 75%;
|
||||
}
|
||||
|
@ -2,11 +2,38 @@
|
||||
@use "filter_box.scss";
|
||||
@import "constants";
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("../fonts/iAWriterMonoS-Regular.woff2");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("../fonts/iAWriterMonoS-Bold.woff2");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("../fonts/iAWriterMonoS-Italic.woff2");
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("../fonts/iAWriterMonoS-BoldItalic.woff2");
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
:root {
|
||||
--ident: 18px;
|
||||
/* --editor-font: "Avenir"; */
|
||||
--editor-font: "Menlo";
|
||||
--editor-font: "iA-Mono", "Menlo";
|
||||
--ui-font: "Arial";
|
||||
--top-bar-bg: rgb(41, 41, 41);
|
||||
--highlight-color: #464cfc;
|
||||
@ -73,6 +100,20 @@ body {
|
||||
color: #5e5e5e;
|
||||
}
|
||||
}
|
||||
.actions {
|
||||
float: right;
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
// border-radius: 5px;
|
||||
// background-color: rgba(77,141,255,0.07);
|
||||
background-color: transparent;
|
||||
padding: 3px;
|
||||
font-family: "IA-Mono", "Menlo";
|
||||
font-size: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,13 @@ export type Notification = {
|
||||
date: Date;
|
||||
};
|
||||
|
||||
export type ActionButton = {
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
orderId?: number;
|
||||
run: () => void;
|
||||
};
|
||||
|
||||
export type AppViewState = {
|
||||
currentPage?: string;
|
||||
showPageNavigator: boolean;
|
||||
@ -23,6 +30,7 @@ export type AppViewState = {
|
||||
allPages: Set<PageMeta>;
|
||||
commands: Map<string, AppCommand>;
|
||||
notifications: Notification[];
|
||||
actionButtons: ActionButton[];
|
||||
|
||||
showFilterBox: boolean;
|
||||
filterBoxLabel: string;
|
||||
@ -45,6 +53,7 @@ export const initialViewState: AppViewState = {
|
||||
allPages: new Set(),
|
||||
commands: new Map(),
|
||||
notifications: [],
|
||||
actionButtons: [],
|
||||
showFilterBox: false,
|
||||
filterBoxHelpText: "",
|
||||
filterBoxLabel: "",
|
||||
@ -60,7 +69,11 @@ export type Action =
|
||||
| { type: "page-saved" }
|
||||
| { type: "start-navigate" }
|
||||
| { type: "stop-navigate" }
|
||||
| { type: "update-commands"; commands: Map<string, AppCommand> }
|
||||
| {
|
||||
type: "update-commands";
|
||||
commands: Map<string, AppCommand>;
|
||||
actionButtons: ActionButton[];
|
||||
}
|
||||
| { type: "show-palette"; context?: string }
|
||||
| { type: "hide-palette" }
|
||||
| { type: "show-notification"; notification: Notification }
|
||||
|
Loading…
Reference in New Issue
Block a user