diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 6fd869f0..73273bed 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,27 +1,27 @@ module.exports = { root: true, env: { - browser: true, - es2021: true + browser: true, + es2021: true, }, - plugins: ['svelte3', '@typescript-eslint'], + plugins: ["svelte3", "@typescript-eslint"], overrides: [ { - files: ['*.svelte'], - processor: 'svelte3/svelte3' - } + files: ["*.svelte"], + processor: "svelte3/svelte3", + }, ], - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - parser: '@typescript-eslint/parser', + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + parser: "@typescript-eslint/parser", parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - extraFileExtensions: ['.svelte'] + ecmaVersion: "latest", + sourceType: "module", + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + extraFileExtensions: [".svelte"], }, settings: { - 'svelte3/typescript': require('typescript'), + "svelte3/typescript": require("typescript"), }, rules: { "a11y-click-events-have-key-events": "off", @@ -30,6 +30,7 @@ module.exports = { "no-async-promise-executor": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-extra-semi": "off", + "@typescript-eslint/ban-ts-comment": "off", "no-useless-escape": "off", }, ignorePatterns: ["*.svg"], diff --git a/src/app/listener.ts b/src/app/listener.ts index 53fa9291..5c04b156 100644 --- a/src/app/listener.ts +++ b/src/app/listener.ts @@ -102,6 +102,7 @@ const listen = async pubkey => { } listener = await network.listen({ + delay: 5000, relays: getUserReadRelays(), filter: [ {kinds: [1, 4], authors: [pubkey], since}, diff --git a/src/partials/Channel.svelte b/src/partials/Channel.svelte index 1383597f..62ab36de 100644 --- a/src/partials/Channel.svelte +++ b/src/partials/Channel.svelte @@ -3,7 +3,7 @@ import {fly} from "svelte/transition" import {navigate} from "svelte-routing" import {prop, path as getPath, reverse, pluck, uniqBy, sortBy, last} from "ramda" - import {sleep, createScroller, Cursor} from "src/util/misc" + import {sleep, timedelta, createScroller, Cursor} from "src/util/misc" import Spinner from "src/partials/Spinner.svelte" import user from "src/agent/user" import {getPersonWithFallback} from "src/agent/tables" @@ -18,7 +18,9 @@ let loading = sleep(30_000) let annotatedMessages = [] let showNewMessages = false - let cursor = new Cursor() + let cursor = new Cursor({ + delta: timedelta(7, "days"), + }) $: { // Group messages so we're only showing the person once per chunk diff --git a/src/partials/Compose.svelte b/src/partials/Compose.svelte index 78e3fed5..4f074d57 100644 --- a/src/partials/Compose.svelte +++ b/src/partials/Compose.svelte @@ -21,6 +21,7 @@ return "nostr:" + nprofile }, decode: link => { + // @ts-ignore return nip19.decode(last(link.split(":"))).data.pubkey }, } @@ -104,7 +105,7 @@ } const onKeyUp = e => { - const {word, trailingSpaces} = getInfo() + const {word} = getInfo() // Populate search data applySearch(word) @@ -146,7 +147,7 @@ const topics = pluck("value", annotations.filter(propEq("prefix", "#"))) // Remove zero-width and non-breaking spaces - content = content.replace(/[\u200B\u00A0]/g, ' ').trim() + content = content.replace(/[\u200B\u00A0]/g, " ").trim() // We're still using old style mention interpolation until NIP-27 // gets merged https://github.com/nostr-protocol/nips/pull/381/files diff --git a/src/partials/ContentEditable.svelte b/src/partials/ContentEditable.svelte index a05d3e15..c9b93d6c 100644 --- a/src/partials/ContentEditable.svelte +++ b/src/partials/ContentEditable.svelte @@ -7,32 +7,42 @@ return true } - if (node.tagName === "DIV") { + if (node.tagName === "DIV" && !node.getAttribute?.("style")) { return true } return false } - const isFancy = node => node instanceof Element && !isLineBreak(node) + const isFancy = node => node instanceof HTMLElement && !isLineBreak(node) const onInput = e => { + const selection = window.getSelection() + const {focusNode: node, focusOffset: offset} = selection + for (const node of input.childNodes) { if (isLineBreak(node)) { continue } // Remove gunk that gets copy/pasted, or bold/italic tags that can be added with hotkeys - if (node instanceof Element && !node.dataset.coracle) { - node.replaceWith(document.createTextNode(node.textContent)) + if (node instanceof HTMLElement && !node.dataset.coracle) { + const text = document.createTextNode(node.textContent) + + if (node.tagName === "DIV") { + const div = document.createElement("div") + + div.appendChild(text) + node.replaceWith(div) + } else { + node.replaceWith(text) + } } } - const selection = window.getSelection() - const {focusNode: node, focusOffset: offset} = selection - // If we're editing something we've already linked, un-link it if (node !== input && node.parentNode !== input && isFancy(node.parentNode)) { + // @ts-ignore node.parentNode.replaceWith(node) selection.collapse(node, offset) input.normalize() diff --git a/src/util/misc.ts b/src/util/misc.ts index d5a2eecb..04466692 100644 --- a/src/util/misc.ts +++ b/src/util/misc.ts @@ -123,7 +123,7 @@ export const poll = (t, cb) => { } export const createScroller = (loadMore, {reverse = false} = {}) => { - const THRESHOLD = 1200 + const THRESHOLD = 2000 // NOTE TO FUTURE SELF // If the scroller is saturating request channels on a slow relay, the @@ -144,7 +144,7 @@ export const createScroller = (loadMore, {reverse = false} = {}) => { } // No need to check all that often - await sleep(1000) + await sleep(500) if (!done) { requestAnimationFrame(check) @@ -164,16 +164,21 @@ export const createScroller = (loadMore, {reverse = false} = {}) => { export const randomChoice = xs => xs[Math.floor(Math.random() * xs.length)] export class Cursor { + delta: number + since: number until: number limit: number count: number - constructor(limit = 20) { + constructor({limit = 50, delta = timedelta(6, "hours")}) { + this.delta = delta + this.since = now() - delta this.until = now() this.limit = limit this.count = 0 } getFilter() { return { + since: this.since, until: this.until, limit: this.limit, } @@ -208,6 +213,8 @@ export class Cursor { // Only paginate part of the way so we can avoid missing stuff this.until -= Math.round(gap * scale * this.limit) } + + this.since = Math.min(this.since, this.until) - this.delta } } @@ -388,7 +395,7 @@ export const hexToBech32 = (prefix, url) => export const bech32ToHex = b32 => utf8.encode(bech32.fromWords(bech32.decode(b32, false).words)) -export const numberFmt = new Intl.NumberFormat +export const numberFmt = new Intl.NumberFormat() export const formatSats = sats => { if (sats < 1_000) return numberFmt.format(sats) diff --git a/src/views/feed/Feed.svelte b/src/views/feed/Feed.svelte index 39a00dcc..cb19fd32 100644 --- a/src/views/feed/Feed.svelte +++ b/src/views/feed/Feed.svelte @@ -3,7 +3,7 @@ import {partition, always, propEq, uniqBy, sortBy, prop} from "ramda" import {fly} from "svelte/transition" import {quantify} from "hurdak/lib/hurdak" - import {createScroller, now, Cursor} from "src/util/misc" + import {createScroller, now, timedelta, Cursor} from "src/util/misc" import {asDisplayEvent, mergeFilter} from "src/util/nostr" import Spinner from "src/partials/Spinner.svelte" import Content from "src/partials/Content.svelte" @@ -15,6 +15,7 @@ export let filter export let relays = [] + export let delta = timedelta(6, "hours") export let shouldDisplay = always(true) export let parentsTimeout = 500 @@ -24,7 +25,7 @@ // Add a short buffer so we can get the most possible results for recent notes const since = now() const maxNotes = 100 - const cursor = new Cursor() + const cursor = new Cursor({delta}) const seen = new Set() const loadBufferedNotes = () => { diff --git a/src/views/person/Likes.svelte b/src/views/person/Likes.svelte index b0b6da63..b6842c7f 100644 --- a/src/views/person/Likes.svelte +++ b/src/views/person/Likes.svelte @@ -1,6 +1,7 @@ - + diff --git a/src/views/person/Notes.svelte b/src/views/person/Notes.svelte index 25231b09..749f0e10 100644 --- a/src/views/person/Notes.svelte +++ b/src/views/person/Notes.svelte @@ -1,4 +1,5 @@ - +