updated the readme
This commit is contained in:
parent
d914db1c1d
commit
3873243a0f
7 changed files with 145 additions and 53 deletions
16
README.md
16
README.md
|
@ -1,6 +1,18 @@
|
||||||
# Nostr Microclient
|
# Personal Microclient
|
||||||
|
|
||||||
using nostr-tools and pwabuilder to play with notes and display them on an installable personal web page.
|
This is an installable personal website that is accessisible through chrome-based and firefox browsers. The website is built with PWA Builder and Lit Web Components. It utilizes the Nostr
|
||||||
|
protocol to connect to my personal relay for fetching recent notes as well as kind 0 notes AKA profile metadata.
|
||||||
|
|
||||||
|
If you're on safari browsers, try visiting the webpage then tapping on the arrow
|
||||||
|
pointing up in the bottom toolbar. Scroll down a bit to tap on "Add to Home Screen".
|
||||||
|
|
||||||
|
If you're on a chromium-based browser you should be able to do the same
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
<ul><li>refactor</li></ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
44
package-lock.json
generated
44
package-lock.json
generated
|
@ -15,11 +15,13 @@
|
||||||
"@thepassle/app-tools": "^0.9.12",
|
"@thepassle/app-tools": "^0.9.12",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"crelt": "^1.0.6",
|
||||||
"express": "^4.21.1",
|
"express": "^4.21.1",
|
||||||
"lazy.js": "^0.5.1",
|
"lazy.js": "^0.5.1",
|
||||||
"lit": "^3.2.1",
|
"lit": "^3.2.1",
|
||||||
"nostr-tools": "^2.10.1",
|
"nostr-tools": "^2.10.1",
|
||||||
"prosemirror-markdown": "^1.13.1",
|
"prosemirror-markdown": "^1.13.1",
|
||||||
|
"prosemirror-menu": "^1.2.4",
|
||||||
"prosemirror-model": "^1.24.1",
|
"prosemirror-model": "^1.24.1",
|
||||||
"prosemirror-state": "^1.4.3",
|
"prosemirror-state": "^1.4.3",
|
||||||
"prosemirror-view": "^1.37.1",
|
"prosemirror-view": "^1.37.1",
|
||||||
|
@ -3046,6 +3048,11 @@
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crelt": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
|
||||||
|
},
|
||||||
"node_modules/crypto-random-string": {
|
"node_modules/crypto-random-string": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
|
||||||
|
@ -4762,6 +4769,27 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prosemirror-commands": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA==",
|
||||||
|
"dependencies": {
|
||||||
|
"prosemirror-model": "^1.0.0",
|
||||||
|
"prosemirror-state": "^1.0.0",
|
||||||
|
"prosemirror-transform": "^1.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prosemirror-history": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"prosemirror-state": "^1.2.2",
|
||||||
|
"prosemirror-transform": "^1.0.0",
|
||||||
|
"prosemirror-view": "^1.31.0",
|
||||||
|
"rope-sequence": "^1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prosemirror-markdown": {
|
"node_modules/prosemirror-markdown": {
|
||||||
"version": "1.13.1",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz",
|
||||||
|
@ -4772,6 +4800,17 @@
|
||||||
"prosemirror-model": "^1.20.0"
|
"prosemirror-model": "^1.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prosemirror-menu": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==",
|
||||||
|
"dependencies": {
|
||||||
|
"crelt": "^1.0.0",
|
||||||
|
"prosemirror-commands": "^1.0.0",
|
||||||
|
"prosemirror-history": "^1.0.0",
|
||||||
|
"prosemirror-state": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prosemirror-model": {
|
"node_modules/prosemirror-model": {
|
||||||
"version": "1.24.1",
|
"version": "1.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz",
|
||||||
|
@ -5052,6 +5091,11 @@
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rope-sequence": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ=="
|
||||||
|
},
|
||||||
"node_modules/rxjs": {
|
"node_modules/rxjs": {
|
||||||
"version": "7.8.1",
|
"version": "7.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||||
|
|
|
@ -21,11 +21,13 @@
|
||||||
"@thepassle/app-tools": "^0.9.12",
|
"@thepassle/app-tools": "^0.9.12",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"crelt": "^1.0.6",
|
||||||
"express": "^4.21.1",
|
"express": "^4.21.1",
|
||||||
"lazy.js": "^0.5.1",
|
"lazy.js": "^0.5.1",
|
||||||
"lit": "^3.2.1",
|
"lit": "^3.2.1",
|
||||||
"nostr-tools": "^2.10.1",
|
"nostr-tools": "^2.10.1",
|
||||||
"prosemirror-markdown": "^1.13.1",
|
"prosemirror-markdown": "^1.13.1",
|
||||||
|
"prosemirror-menu": "^1.2.4",
|
||||||
"prosemirror-model": "^1.24.1",
|
"prosemirror-model": "^1.24.1",
|
||||||
"prosemirror-state": "^1.4.3",
|
"prosemirror-state": "^1.4.3",
|
||||||
"prosemirror-view": "^1.37.1",
|
"prosemirror-view": "^1.37.1",
|
||||||
|
|
BIN
public/assets/icons/casto_kingdom.png
Executable file
BIN
public/assets/icons/casto_kingdom.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
|
@ -1,40 +1,32 @@
|
||||||
import { Plugin } from 'prosemirror-state';
|
// menu-plugin.ts
|
||||||
|
import { MenuItem } from "prosemirror-menu";
|
||||||
|
import { menuBar } from "prosemirror-menu";
|
||||||
|
import { toggleMark } from "prosemirror-commands";
|
||||||
|
import { Plugin } from "prosemirror-state";
|
||||||
|
|
||||||
export const plusButtonPlugin = new Plugin({
|
// Modify the menuBar function to accept customSchema as a parameter
|
||||||
view(editorView) {
|
export function createMenuPlugin(customSchema: any) {
|
||||||
const button = document.createElement('button');
|
const boldButton = new MenuItem({
|
||||||
button.textContent = '+';
|
title: "Bold",
|
||||||
button.className = 'plus-button'
|
run: toggleMark(customSchema.marks.bold),
|
||||||
|
active: (state) => state.selection.$head.marks().some(mark => mark.type === customSchema.marks.bold),
|
||||||
button.style.position = 'absolute';
|
|
||||||
button.style.zIndex = '10';
|
|
||||||
button.style.display = 'none'; // Hide initially
|
|
||||||
|
|
||||||
editorView.dom.appendChild(button);
|
|
||||||
|
|
||||||
button.addEventListener('click', () => {
|
|
||||||
console.log('Plus button clicked');
|
|
||||||
// Add logic to open dropdown or execute commands
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
const italicButton = new MenuItem({
|
||||||
update(view) {
|
title: "Italic",
|
||||||
const { $from } = view.state.selection;
|
run: toggleMark(customSchema.marks.italic),
|
||||||
|
active: (state) => state.selection.$head.marks().some(mark => mark.type === customSchema.marks.italic),
|
||||||
|
});
|
||||||
|
|
||||||
// Only show the button when the cursor is in a text block with no content
|
const menuContent = [
|
||||||
if ($from.parent.isTextblock && $from.parent.content.size === 0) {
|
[boldButton, italicButton] // Array of buttons or other menu items
|
||||||
const coords = view.coordsAtPos($from.pos);
|
];
|
||||||
// Position the button relative to the cursor
|
|
||||||
button.style.top = `${coords.top + window.scrollY}px`; // Added scroll offset for better positioning
|
menuBar({
|
||||||
button.style.left = `${coords.left + window.scrollX - 30}px`; // Added scroll offset
|
content: menuContent,
|
||||||
button.style.display = 'block'; // Make the button visible
|
floating: true,
|
||||||
} else {
|
});
|
||||||
button.style.display = 'none'; // Hide the button when not in valid position
|
return new Plugin({
|
||||||
}
|
|
||||||
},
|
})
|
||||||
destroy() {
|
}
|
||||||
button.remove(); // Cleanup on destroy
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ import { toggleMark } from 'prosemirror-commands';
|
||||||
import {undo, redo, history} from 'prosemirror-history'
|
import {undo, redo, history} from 'prosemirror-history'
|
||||||
import { baseKeymap } from 'prosemirror-commands';
|
import { baseKeymap } from 'prosemirror-commands';
|
||||||
|
|
||||||
import { plusButtonPlugin } from '../../components/menu-plugin';
|
import { menuBar } from 'prosemirror-menu';
|
||||||
|
import {createMenuPlugin} from '../../components/menu-plugin'
|
||||||
|
|
||||||
|
|
||||||
|
export const customSchema = new Schema({
|
||||||
const customSchema = new Schema({
|
|
||||||
nodes: {
|
nodes: {
|
||||||
text: {
|
text: {
|
||||||
group: 'inline',
|
group: 'inline',
|
||||||
|
@ -79,8 +79,11 @@ const customSchema = new Schema({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create the menu plugin
|
||||||
|
const menuPlugin = createMenuPlugin(customSchema);
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
function insertStar(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
|
function insertStar(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
|
||||||
const type = customSchema.nodes.star;
|
const type = customSchema.nodes.star;
|
||||||
const { $from } = state.selection;
|
const { $from } = state.selection;
|
||||||
|
|
||||||
|
@ -98,7 +101,7 @@ const customSchema = new Schema({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLink(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
|
function toggleLink(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
|
||||||
let {doc, selection} = state
|
let {doc, selection} = state
|
||||||
if (selection.empty) return false
|
if (selection.empty) return false
|
||||||
let attrs = null
|
let attrs = null
|
||||||
|
@ -111,7 +114,7 @@ const customSchema = new Schema({
|
||||||
|
|
||||||
|
|
||||||
// Keymap
|
// Keymap
|
||||||
const customKeymap = keymap({
|
const customKeymap = keymap({
|
||||||
'Ctrl-Space': insertStar,
|
'Ctrl-Space': insertStar,
|
||||||
"Ctrl-b": (state, dispatch) => {
|
"Ctrl-b": (state, dispatch) => {
|
||||||
console.log("Ctrl-b pressed, toggling shouting mark...");
|
console.log("Ctrl-b pressed, toggling shouting mark...");
|
||||||
|
@ -165,9 +168,16 @@ export class AppWrite extends LitElement {
|
||||||
console.error('Editor container not here');
|
console.error('Editor container not here');
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const doc = customSchema.nodes.doc.createAndFill();
|
||||||
|
if (!doc) {
|
||||||
|
console.error("failed to create initial document")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const state = EditorState.create({
|
const state = EditorState.create({
|
||||||
schema: customSchema,
|
doc,
|
||||||
plugins: [
|
plugins: [menuPlugin,
|
||||||
|
|
||||||
|
|
||||||
history(),
|
history(),
|
||||||
keymap({
|
keymap({
|
||||||
|
@ -176,10 +186,13 @@ export class AppWrite extends LitElement {
|
||||||
}),
|
}),
|
||||||
keymap(baseKeymap),
|
keymap(baseKeymap),
|
||||||
// Add the plus-button plugin here
|
// Add the plus-button plugin here
|
||||||
plusButtonPlugin
|
customKeymap
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const selection = state.selection;
|
||||||
let view = new EditorView(this.editorContainer, {
|
let view = new EditorView(this.editorContainer, {
|
||||||
state,
|
state,
|
||||||
dispatchTransaction(transaction) {
|
dispatchTransaction(transaction) {
|
||||||
|
@ -195,6 +208,13 @@ export class AppWrite extends LitElement {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
if(!this.editorView) {
|
||||||
|
this.editorView;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
disconnectedCallback(): void {
|
disconnectedCallback(): void {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
if (this.editorView) {
|
if (this.editorView) {
|
||||||
|
|
|
@ -445,4 +445,26 @@ export const styles = css`
|
||||||
background-color: #45a049;
|
background-color: #45a049;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add these styles to your component's CSS */
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu button {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu button:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
`;
|
`;
|
Loading…
Reference in a new issue