updated the readme

This commit is contained in:
miggymofongo 2025-01-04 23:50:59 -04:00
parent d914db1c1d
commit 3873243a0f
7 changed files with 145 additions and 53 deletions

View file

@ -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
View file

@ -15,11 +15,13 @@
"@thepassle/app-tools": "^0.9.12",
"axios": "^1.7.7",
"cors": "^2.8.5",
"crelt": "^1.0.6",
"express": "^4.21.1",
"lazy.js": "^0.5.1",
"lit": "^3.2.1",
"nostr-tools": "^2.10.1",
"prosemirror-markdown": "^1.13.1",
"prosemirror-menu": "^1.2.4",
"prosemirror-model": "^1.24.1",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.37.1",
@ -3046,6 +3048,11 @@
"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": {
"version": "2.0.0",
"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"
}
},
"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": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz",
@ -4772,6 +4800,17 @@
"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": {
"version": "1.24.1",
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz",
@ -5052,6 +5091,11 @@
"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": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",

View file

@ -21,11 +21,13 @@
"@thepassle/app-tools": "^0.9.12",
"axios": "^1.7.7",
"cors": "^2.8.5",
"crelt": "^1.0.6",
"express": "^4.21.1",
"lazy.js": "^0.5.1",
"lit": "^3.2.1",
"nostr-tools": "^2.10.1",
"prosemirror-markdown": "^1.13.1",
"prosemirror-menu": "^1.2.4",
"prosemirror-model": "^1.24.1",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.37.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View file

@ -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({
view(editorView) {
const button = document.createElement('button');
button.textContent = '+';
button.className = 'plus-button'
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
// Modify the menuBar function to accept customSchema as a parameter
export function createMenuPlugin(customSchema: any) {
const boldButton = new MenuItem({
title: "Bold",
run: toggleMark(customSchema.marks.bold),
active: (state) => state.selection.$head.marks().some(mark => mark.type === customSchema.marks.bold),
});
return {
update(view) {
const { $from } = view.state.selection;
const italicButton = new MenuItem({
title: "Italic",
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
if ($from.parent.isTextblock && $from.parent.content.size === 0) {
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
button.style.left = `${coords.left + window.scrollX - 30}px`; // Added scroll offset
button.style.display = 'block'; // Make the button visible
} else {
button.style.display = 'none'; // Hide the button when not in valid position
const menuContent = [
[boldButton, italicButton] // Array of buttons or other menu items
];
menuBar({
content: menuContent,
floating: true,
});
return new Plugin({
})
}
},
destroy() {
button.remove(); // Cleanup on destroy
},
};
},
});

View file

@ -16,11 +16,11 @@ import { toggleMark } from 'prosemirror-commands';
import {undo, redo, history} from 'prosemirror-history'
import { baseKeymap } from 'prosemirror-commands';
import { plusButtonPlugin } from '../../components/menu-plugin';
import { menuBar } from 'prosemirror-menu';
import {createMenuPlugin} from '../../components/menu-plugin'
const customSchema = new Schema({
export const customSchema = new Schema({
nodes: {
text: {
group: 'inline',
@ -79,6 +79,9 @@ const customSchema = new Schema({
},
});
// Create the menu plugin
const menuPlugin = createMenuPlugin(customSchema);
// Commands
function insertStar(state: EditorState, dispatch?: (tr: Transaction) => void): boolean {
const type = customSchema.nodes.star;
@ -165,9 +168,16 @@ export class AppWrite extends LitElement {
console.error('Editor container not here');
return
}
const doc = customSchema.nodes.doc.createAndFill();
if (!doc) {
console.error("failed to create initial document")
return;
}
const state = EditorState.create({
schema: customSchema,
plugins: [
doc,
plugins: [menuPlugin,
history(),
keymap({
@ -176,10 +186,13 @@ export class AppWrite extends LitElement {
}),
keymap(baseKeymap),
// Add the plus-button plugin here
plusButtonPlugin
customKeymap
],
});
const selection = state.selection;
let view = new EditorView(this.editorContainer, {
state,
dispatchTransaction(transaction) {
@ -195,6 +208,13 @@ export class AppWrite extends LitElement {
}
/* connectedCallback(): void {
super.connectedCallback();
if(!this.editorView) {
this.editorView;
}
} */
disconnectedCallback(): void {
super.disconnectedCallback();
if (this.editorView) {

View file

@ -445,4 +445,26 @@ export const styles = css`
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;
}
`;