40 |
41 |
{props.data!.title}
42 |
props.data!.renderModal(dom, actions)} class="modal-content" />
43 |
44 |
45 | );
46 | }
47 |
48 | /* ---- modal controller -------------------------------- */
49 |
50 | export interface ModalState {
51 | data: null | {
52 | title: string,
53 | renderModal: RenderModalFn,
54 | }
55 | }
56 |
57 | export const initialModalState: ModalState = {
58 | data: null
59 | }
60 |
61 | export interface ModalController {
62 | showModal(state: ModalState): ModalState;
63 | hideModal(state: ModalState): ModalState;
64 | computeProps(state: ModalState): ModalProps;
65 | }
66 |
67 | export namespace ModalController {
68 | export const showModal = (
69 | state: ModalState,
70 | data: {
71 | title: string,
72 | renderModal: RenderModalFn,
73 | }
74 | ): ModalState => {
75 | return {
76 | ...state,
77 | data: {
78 | title: data.title,
79 | renderModal: data.renderModal
80 | }
81 | }
82 | };
83 |
84 | export const hideModal = (state: ModalState): ModalState => {
85 | return {
86 | ...state,
87 | data: null
88 | }
89 | };
90 |
91 | export const computeProps = (state: ModalState): Omit
=> {
92 | return {
93 | data: state.data
94 | };
95 | };
96 | }
97 |
98 | /* ---- modal comands ----------------------------------- */
99 |
100 | declare module "@common/extensions/noteworthy-extension" {
101 | export interface CommunityExtensionCommands {
102 | showModal: CommandSpec<
103 | {
104 | title: string,
105 | renderModal: RenderModalFn,
106 | },
107 | void
108 | >,
109 | hideModal: CommandSpec<{}, void>
110 | }
111 | }
112 |
113 | export const initModalCommands = (
114 | setModalState: (setter: (state: ModalState) => ModalState) => void,
115 | api: NoteworthyExtensionApi
116 | ): void => {
117 | api.registerCommand("showModal", async (args) => {
118 | setModalState((state: ModalState) =>
119 | ModalController.showModal(state, args)
120 | );
121 | });
122 |
123 | api.registerCommand("hideModal", async () => {
124 | setModalState((state: ModalState) =>
125 | ModalController.hideModal(state)
126 | );
127 | });
128 | }
129 |
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/ModalNewFile/ModalNewFile.css:
--------------------------------------------------------------------------------
1 | .modal-newfile .input-box {
2 | background-color: #e0e0e0;
3 | padding: 0.5rem;
4 | font-family: var(--font-ui-monospace);
5 | }
6 |
7 | .modal-newfile .newfile-folder {
8 | display: flex;
9 | }
10 |
11 | .modal-newfile .newfile-folder-workspace {
12 | color: #666;
13 | user-select: none;
14 | }
15 |
16 | .modal-newfile input.newfile-folder-input {
17 | flex-grow: 1;
18 | background-color: unset;
19 | border: none;
20 | font-family: unset;
21 | width: unset;
22 | }
23 |
24 | .modal-newfile input.newfile-folder-input:focus {
25 | outline: none;
26 | }
27 |
28 | .modal-newfile input.newfile-name {
29 | display: block;
30 | outline: none;
31 | border: none;
32 | }
33 |
34 | .modal-newfile > div.section {
35 | margin: 0.5em;
36 | }
37 |
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/ModalNewFile/ModalNewFile.tsx:
--------------------------------------------------------------------------------
1 | import { createSignal } from "solid-js";
2 | import "./ModalNewFile.css"
3 |
4 | export interface ModalNewFileProps {
5 | promptFilePath: () => Promise,
6 | handleSubmit: (name: string) => void;
7 | handleCancel: () => void;
8 | workspaceRoot: string
9 | }
10 |
11 | export const ModalNewFile = (props: ModalNewFileProps) => {
12 | const [selectedFolder, setSelectedFolder] = createSignal(null);
13 | const [selectedFilename, setSelectedFilename] = createSignal(null);
14 |
15 | const setFolderRoot = () => {
16 | setSelectedFolder(props.workspaceRoot);
17 | }
18 |
19 | const setFolderPrompt = () => {
20 | console.log("[setFolderCurrent]");
21 | props.promptFilePath().then((path: string) => {
22 | console.log(`selected ${path}`);
23 | setSelectedFolder(path);
24 | }, (err) => {
25 | console.error("no file path!");
26 | });
27 | }
28 |
29 | return (
30 |
31 | {/*
32 | WORKSPACE/
33 | */}
34 | setSelectedFolder(evt.target.value) }
39 | />
40 |
41 |
42 |
{selectedFolder()}
43 |
44 |
45 |
46 |
47 |
48 | {/*
49 |
50 |
*/}
51 |
52 |
53 |
59 |
67 |
68 |
);
69 | }
70 |
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/bibliography.tsx:
--------------------------------------------------------------------------------
1 | import { createResource } from "solid-js";
2 | import { MainIpcHandlers } from "@main/MainIPC";
3 |
4 | ////////////////////////////////////////////////////////////////////////////////
5 |
6 | export interface BibliographyProps {
7 | proxy: MainIpcHandlers;
8 | citationKeys: string[];
9 | }
10 |
11 | interface BibliographyData {
12 | data: string | null;
13 | }
14 |
15 | export const BibliographyComponent = (props: BibliographyProps) => {
16 |
17 | const [citations] = createResource(
18 | () => props,
19 | async (pr, getPrev) => {
20 | const bibliography = await pr.proxy.citations.generateBibliography(pr.citationKeys);
21 | console.log(bibliography);
22 | return { data: bibliography };
23 | }
24 | );
25 |
26 | return (
27 |
Bibliography
28 |
29 |
);
30 | }
31 |
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/calendarTab.tsx:
--------------------------------------------------------------------------------
1 | import { For } from "solid-js";
2 |
3 | interface ICalendarProps {
4 | year: number;
5 | month: number;
6 | }
7 |
8 | const WEEKDAYS = ["Su", "M","Tu","W","Th","F","Sa"];
9 | const MONTHS = [
10 | "January", "February", "March", "April",
11 | "May", "June", "July", "August",
12 | "September", "October", "November", "December"
13 | ];
14 |
15 | export const Calendar = (props:ICalendarProps) => {
16 | // get current weekday and last day of prev/current month
17 | let prev:number = new Date(props.year, props.month, 0).getDate();
18 | let last:number = new Date(props.year, props.month+1, 0).getDate();
19 | let today:Date = new Date(props.year, props.month, 1);
20 | // create calendar table
21 | return (
22 |
27 |
28 | {/* Header Row */}
29 |
30 | {day =>
31 | ({day} | )
32 | }
33 |
34 | {/* Calendar Rows */}
35 | {rowIdx => (
36 | {colIdx => {
37 | let idx = rowIdx*7 + colIdx;
38 | let order:number = 0;
39 | // determine date label
40 | let num:number = 1 + idx - today.getDay();
41 | if(num < 1) { order = -1; num = prev - 1 - num; }
42 | else if(num > last) { order = 1; num = num - last; }
43 | // element
44 | if(order == 0){ return ({num} | ); }
45 | else { return ({num} | ); }
46 | }}
47 |
)}
48 |
49 |
)
50 | }
51 |
52 | export const CalendarTab = () => {
53 | let today = new Date(Date.now());
54 | return (
)
55 | }
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/editorComponent.tsx:
--------------------------------------------------------------------------------
1 | // solidjs
2 | import { render } from "solid-js/web";
3 | import { createEffect, createSignal, onCleanup } from "solid-js";
4 |
5 | ////////////////////////////////////////////////////////////////////////////////
6 |
7 | export interface EditorComponentProps {
8 |
9 | }
10 |
11 | export const EditorComponent = (props: EditorComponentProps) => {
12 |
13 |
14 | const timer = setInterval(() => {
15 |
16 | }, 2000);
17 |
18 | onCleanup(() => clearInterval(timer));
19 | }
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/explorer.tsx:
--------------------------------------------------------------------------------
1 | import { IDirEntryMeta } from "@common/files";
2 | import { For } from "solid-js";
3 |
4 | export interface IFolderMarker {
5 | folderMarker:true,
6 | path:string,
7 | pathSuffix:string,
8 | name:string,
9 | }
10 |
11 | interface IFileExplorerProps {
12 | fileTree:[IFolderMarker, IDirEntryMeta[]][];
13 | activeHash:string|null;
14 | handleClick:(evt:MouseEvent)=>void;
15 | }
16 | export const FileExplorer = (props:IFileExplorerProps) => {
17 | return (Empty!
}>
18 | {([folder, files])=>(<>
19 | file.hash == props.activeHash ) === undefined}
24 | >{folder.pathSuffix}
25 |
26 | Empty Folder
}>
27 | {(entry)=>(
28 | {entry.name}
34 | )}
35 |
36 |
37 | >)}
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/historyTab.tsx:
--------------------------------------------------------------------------------
1 | import { IFileMeta } from "@common/files";
2 | import { For, Suspense } from "solid-js";
3 |
4 | ////////////////////////////////////////////////////////////
5 |
6 | interface IHistoryTabProps {
7 | //outline: IOutline | null;
8 | navHistory: { history: IFileMeta[], currentIdx: number };
9 | handleHistoryClick: (evt:MouseEvent) => void;
10 | }
11 |
12 | export const HistoryTab = (props: IHistoryTabProps) => {
13 | // render
14 | return (loading...
);
3 | }
--------------------------------------------------------------------------------
/noteworthy-electron/src/renderer/src/ui/outlineTab.tsx:
--------------------------------------------------------------------------------
1 | import { For, createResource, Suspense } from "solid-js";
2 | import { IOutline, IOutlineEntry } from "@main/plugins/outline-plugin";
3 |
4 | ////////////////////////////////////////////////////////////
5 |
6 | interface IOutlineTabProps {
7 | //outline: IOutline | null;
8 | getOutline: () => Promise