diff --git a/android/app/build.gradle b/android/app/build.gradle index c32f4e24..543c12a8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,7 +7,7 @@ android { applicationId "social.flotilla" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 3 + versionCode 4 versionName "0.2.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 41ef2f04..fcef801f 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -9,6 +9,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { + implementation project(':capacitor-app') implementation project(':nostr-signer-capacitor-plugin') } diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 4d2147fb..5d3c2a95 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -2,5 +2,8 @@ include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') +include ':capacitor-app' +project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') + include ':nostr-signer-capacitor-plugin' project(':nostr-signer-capacitor-plugin').projectDir = new File('../node_modules/nostr-signer-capacitor-plugin/android') diff --git a/package-lock.json b/package-lock.json index 75259af1..085a0bdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,10 @@ "name": "flotilla", "version": "0.2.4", "dependencies": { - "@capacitor/android": "^6.1.2", - "@capacitor/cli": "^6.1.2", - "@capacitor/core": "^6.1.2", + "@capacitor/android": "^7.0.1", + "@capacitor/app": "^7.0.0", + "@capacitor/cli": "^6.2.0", + "@capacitor/core": "^7.0.1", "@noble/curves": "^1.5.0", "@noble/hashes": "^1.4.0", "@poppanator/sveltekit-svg": "^4.2.1", @@ -1794,12 +1795,21 @@ "license": "MIT" }, "node_modules/@capacitor/android": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-6.1.2.tgz", - "integrity": "sha512-Yh0gQDY1bgRrL25J6ecIlvvs2kF8iNSwIPXjyw6Yz9mnwYxBazF5KZbjpKtGPnJgicJhFkYGsqOkEtxrve0EoQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-7.0.1.tgz", + "integrity": "sha512-jukJJHfkcyEBOkFBJRD3EwXMIIQo7lSv0ExPWgsIliPdGXLAj6ElvK2JaYEzec3vKyLc4RTNFVv0PMEU0vnImg==", "license": "MIT", "peerDependencies": { - "@capacitor/core": "^6.1.0" + "@capacitor/core": "^7.0.0" + } + }, + "node_modules/@capacitor/app": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-7.0.0.tgz", + "integrity": "sha512-/UFwfPFsw/Jen6vjrV0lfTBOQWSaDDdmrYXKpYg4Xn8hwj0xrrRPXxC43j7VmPoj9AFMVPA+hx94ygqjChPASQ==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=7.0.0" } }, "node_modules/@capacitor/assets": { @@ -2105,14 +2115,13 @@ } }, "node_modules/@capacitor/cli": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-6.1.2.tgz", - "integrity": "sha512-HKCNGE0RP8U7aiEF2vg5wTivJROS8BVfu8a3yYJb1mRQvzv+czpmtHNsTWS/WukvwoxUjyjRmsNQSAACHfMTmQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-6.2.0.tgz", + "integrity": "sha512-EWcXG39mZh35zrHhOqzN1ILeSyMRyEqWVtQDXqMGjCXYRH6b6p5TvyvLDN8ZNy26tbhI3i79gfrgirt+mNwuuw==", "license": "MIT", "dependencies": { "@ionic/cli-framework-output": "^2.2.5", "@ionic/utils-fs": "^3.1.6", - "@ionic/utils-process": "^2.1.11", "@ionic/utils-subprocess": "2.1.11", "@ionic/utils-terminal": "^2.3.3", "commander": "^9.3.0", @@ -2216,9 +2225,9 @@ } }, "node_modules/@capacitor/core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-6.1.2.tgz", - "integrity": "sha512-xFy1/4qLFLp5WCIzIhtwUuVNNoz36+V7/BzHmLqgVJcvotc4MMjswW/TshnPQaLLujEOaLkA4h8ZJ0uoK3ImGg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.0.1.tgz", + "integrity": "sha512-1Ob9bvA/p8g8aNwK6VesxEekGXowLVf6APjkW4LRnr05H+7z/bke+Q5pn9zqh/GgTbIxAQ/rwZrAZvvxkdm1UA==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -2774,42 +2783,6 @@ "node": ">=16.0.0" } }, - "node_modules/@ionic/utils-object": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", - "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-process": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", - "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", - "license": "MIT", - "dependencies": { - "@ionic/utils-object": "2.1.6", - "@ionic/utils-terminal": "2.3.5", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "tree-kill": "^1.2.2", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-process/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, "node_modules/@ionic/utils-stream": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", @@ -4981,9 +4954,9 @@ } }, "node_modules/@welshman/signer/node_modules/@noble/hashes": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", - "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", "license": "MIT", "engines": { "node": "^14.21.3 || >=16" diff --git a/package.json b/package.json index ecee9e86..0aabd447 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,10 @@ }, "type": "module", "dependencies": { - "@capacitor/android": "^6.1.2", - "@capacitor/cli": "^6.1.2", - "@capacitor/core": "^6.1.2", + "@capacitor/android": "^7.0.1", + "@capacitor/app": "^7.0.0", + "@capacitor/cli": "^6.2.0", + "@capacitor/core": "^7.0.1", "@noble/curves": "^1.5.0", "@noble/hashes": "^1.4.0", "@poppanator/sveltekit-svg": "^4.2.1", diff --git a/src/app/notifications.ts b/src/app/notifications.ts index f9d70660..5d7a79b6 100644 --- a/src/app/notifications.ts +++ b/src/app/notifications.ts @@ -3,16 +3,9 @@ import {synced, throttled} from "@welshman/store" import {pubkey} from "@welshman/app" import {prop, spec, identity, now, groupBy} from "@welshman/lib" import type {TrustedEvent} from "@welshman/util" -import {MESSAGE, COMMENT, getTagValue} from "@welshman/util" +import {MESSAGE, THREAD, COMMENT, getTagValue} from "@welshman/util" import {makeSpacePath, makeChatPath, makeThreadPath, makeRoomPath} from "@app/routes" -import { - THREAD_FILTER, - COMMENT_FILTER, - chats, - getUrlsForEvent, - userRoomsByUrl, - repositoryStore, -} from "@app/state" +import {chats, getUrlsForEvent, userRoomsByUrl, repositoryStore} from "@app/state" // Checked state @@ -60,7 +53,10 @@ export const notifications = derived( } } - const allThreadEvents = $repository.query([THREAD_FILTER, COMMENT_FILTER]) + const allThreadEvents = $repository.query([ + {kinds: [THREAD]}, + {kinds: [COMMENT], "#K": [String(THREAD)]}, + ]) const allMessageEvents = $repository.query([{kinds: [MESSAGE]}]) for (const [url, rooms] of $userRoomsByUrl.entries()) { diff --git a/src/app/state.ts b/src/app/state.ts index b576e715..de9ac316 100644 --- a/src/app/state.ts +++ b/src/app/state.ts @@ -80,10 +80,6 @@ export const GENERAL = "_" export const PROTECTED = ["-"] -export const LEGACY_MESSAGE = 209 - -export const LEGACY_THREAD = 309 - export const INDEXER_RELAYS = [ "wss://purplepag.es/", "wss://relay.damus.io/", @@ -118,13 +114,6 @@ export const IMGPROXY_URL = "https://imgproxy.coracle.social" export const REACTION_KINDS = [REACTION, ZAP_RESPONSE] -export const THREAD_FILTER: Filter = {kinds: [THREAD, LEGACY_THREAD]} - -export const COMMENT_FILTER: Filter = { - kinds: [COMMENT], - "#K": [String(THREAD), String(LEGACY_THREAD)], -} - export const NIP46_PERMS = "nip04_encrypt,nip04_decrypt,nip44_encrypt,nip44_decrypt," + [CLIENT_AUTH, AUTH_JOIN, MESSAGE, THREAD, COMMENT, GROUPS, WRAP, REACTION] @@ -463,24 +452,9 @@ export const chatSearch = derived(chats, $chats => // Messages -// TODO: remove support for legacy messages -export const adaptLegacyMessage = (event: TrustedEvent) => { - if (event.kind === LEGACY_MESSAGE) { - let room = event.tags.find(nthEq(0, "~"))?.[1] || GENERAL - - if (room === "general") { - room = GENERAL - } - - return {...event, kind: MESSAGE, tags: [...event.tags, tagRoom(room, "")]} - } - - return event -} - export const messages = derived( - deriveEvents(repository, {filters: [{kinds: [MESSAGE, LEGACY_MESSAGE]}]}), - $events => $events.map(adaptLegacyMessage), + deriveEvents(repository, {filters: [{kinds: [MESSAGE]}]}), + $events => $events, ) // Nip29 diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index a946c4a5..cb2b8a5f 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,6 +3,7 @@ import {onMount} from "svelte" import {nip19} from "nostr-tools" import {get, derived} from "svelte/store" + import {App} from "@capacitor/app" import {dev} from "$app/environment" import {bytesToHex, hexToBytes} from "@noble/hashes/utils" import {identity, sleep, take, sortBy, ago, now, HOUR, WEEK, MONTH, Worker} from "@welshman/lib" @@ -85,6 +86,14 @@ setupTracking() setupAnalytics() + App.addListener("backButton", () => { + if (window.history.length > 1) { + window.history.back() + } else { + App.exitApp() + } + }) + ready = initStorage("flotilla", 5, { relays: storageAdapters.fromCollectionStore("url", relays, {throttle: 3000}), handles: storageAdapters.fromCollectionStore("nip05", handles, {throttle: 3000}), diff --git a/src/routes/spaces/[relay]/+layout.svelte b/src/routes/spaces/[relay]/+layout.svelte index 2c3dbb17..a58c3fd1 100644 --- a/src/routes/spaces/[relay]/+layout.svelte +++ b/src/routes/spaces/[relay]/+layout.svelte @@ -2,7 +2,7 @@ import {onMount} from "svelte" import {page} from "$app/stores" import {ago, WEEK} from "@welshman/lib" - import {GROUPS, MESSAGE, DELETE} from "@welshman/util" + import {GROUPS, THREAD, COMMENT, MESSAGE, DELETE} from "@welshman/util" import {subscribe} from "@welshman/app" import Page from "@lib/components/Page.svelte" import SecondaryNav from "@lib/components/SecondaryNav.svelte" @@ -12,7 +12,7 @@ import {pushModal} from "@app/modal" import {setChecked} from "@app/notifications" import {checkRelayConnection, checkRelayAuth, checkRelayAccess} from "@app/commands" - import {decodeRelay, userRoomsByUrl, THREAD_FILTER, COMMENT_FILTER} from "@app/state" + import {decodeRelay, userRoomsByUrl} from "@app/state" import {pullConservatively} from "@app/requests" import {notifications} from "@app/notifications" @@ -56,8 +56,8 @@ pullConservatively({ relays, filters: [ - {...THREAD_FILTER, since}, - {...COMMENT_FILTER, since}, + {kinds: [THREAD], since}, + {kinds: [COMMENT], "#K": [String(THREAD)], since}, ], }) diff --git a/src/routes/spaces/[relay]/[room]/+page.svelte b/src/routes/spaces/[relay]/[room]/+page.svelte index 759c1ebf..fc384ffe 100644 --- a/src/routes/spaces/[relay]/[room]/+page.svelte +++ b/src/routes/spaces/[relay]/[room]/+page.svelte @@ -33,7 +33,6 @@ deriveEventsForUrl, GENERAL, tagRoom, - LEGACY_MESSAGE, userRoomsByUrl, displayChannel, } from "@app/state" @@ -47,16 +46,9 @@ const content = popKey("content") || "" const url = decodeRelay($page.params.relay) const relay = deriveRelay(url) - const legacyRoom = room === GENERAL ? "general" : room const feeds = feedsFromFilter({kinds: [MESSAGE], "#h": [room]}) - const events = throttled( - 300, - deriveEventsForUrl(url, [ - {kinds: [MESSAGE], "#h": [room]}, - {kinds: [LEGACY_MESSAGE], "#~": [legacyRoom]}, - ]), - ) + const events = throttled(300, deriveEventsForUrl(url, [{kinds: [MESSAGE], "#h": [room]}])) const ctrl = createFeedController({ useWindowing: true, diff --git a/src/routes/spaces/[relay]/threads/+page.svelte b/src/routes/spaces/[relay]/threads/+page.svelte index 10d2cc89..0f0d4076 100644 --- a/src/routes/spaces/[relay]/threads/+page.svelte +++ b/src/routes/spaces/[relay]/threads/+page.svelte @@ -3,7 +3,7 @@ import {derived} from "svelte/store" import {page} from "$app/stores" import {sortBy, min, nthEq, sleep} from "@welshman/lib" - import {getListTags, getPubkeyTagValues} from "@welshman/util" + import {THREAD, COMMENT, getListTags, getPubkeyTagValues} from "@welshman/util" import {throttled} from "@welshman/store" import {feedFromFilters, makeIntersectionFeed, makeRelayFeed} from "@welshman/feeds" import {createFeedController, userMutes} from "@welshman/app" @@ -16,14 +16,16 @@ import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte" import ThreadItem from "@app/components/ThreadItem.svelte" import ThreadCreate from "@app/components/ThreadCreate.svelte" - import {THREAD_FILTER, COMMENT_FILTER, decodeRelay, deriveEventsForUrl} from "@app/state" + import {decodeRelay, deriveEventsForUrl} from "@app/state" import {setChecked} from "@app/notifications" import {pushModal} from "@app/modal" const url = decodeRelay($page.params.relay) - const feed = feedFromFilters([THREAD_FILTER, COMMENT_FILTER]) - const threads = deriveEventsForUrl(url, [THREAD_FILTER]) - const comments = deriveEventsForUrl(url, [COMMENT_FILTER]) + const threadFilter = {kinds: [THREAD]} + const commentFilter = {kinds: [COMMENT], "#K": [String(THREAD)]} + const feed = feedFromFilters([threadFilter, commentFilter]) + const threads = deriveEventsForUrl(url, [threadFilter]) + const comments = deriveEventsForUrl(url, [commentFilter]) const mutedPubkeys = getPubkeyTagValues(getListTags($userMutes)) const events = throttled(