Compare commits

..

2 Commits

189 changed files with 6161 additions and 2677 deletions
+1
View File
@@ -4,6 +4,7 @@ ios
build
# Git
.git
.gitignore
# Env files (keep .env for build; exclude local overrides)
+1 -1
View File
@@ -19,6 +19,6 @@ VITE_DEFAULT_SEARCH_RELAYS=relay.ditto.pub,antiprimal.net,relay.vertexlab.io
VITE_DEFAULT_MESSAGING_RELAYS=auth.nostr1.com,relay.keychat.io,relay.ditto.pub
VITE_SIGNER_RELAYS=relay.nsec.app,ephemeral.snowflare.cc,bucket.coracle.social
VITE_VAPID_PUBLIC_KEY=BIt2D4BdgdbCowD_0d3Np6GbrIGHxd7aIEUeZNe3hQuRlHz02OhzvDaai0XSFoJYVzSzdMjdyW-QhvW9_yq8j4Y
VITE_THUMBNAIL_URL=https://vthumbs.coracle.social
VITE_THUMBNAIL_URL=
VITE_GLITCHTIP_API_KEY=
GLITCHTIP_AUTH_TOKEN=
+1 -2
View File
@@ -1,5 +1,4 @@
src/assets
.claude
target
build
.idea
@@ -14,4 +13,4 @@ ios/App/Pods/
android/capacitor-cordova-android-plugins
android/app/src/androidTest
android/app/src/test
node_modules
@@ -1,17 +1,12 @@
name: Container Image Build and Publish
name: Docker
on:
push:
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: gitea.coracle.social
IMAGE_NAME: coracle/flotilla
REGISTRY: ghcr.io
IMAGE_NAME: coracle-social/flotilla
jobs:
build-and-push-image:
@@ -28,8 +23,8 @@ jobs:
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: hodlbod
password: ${{ secrets.PACKAGE_TOKEN }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
@@ -37,7 +32,6 @@ jobs:
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
- name: Set up Docker Buildx
@@ -51,7 +45,6 @@ jobs:
with:
context: .
push: true
target: production
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+4 -2
View File
@@ -27,10 +27,13 @@ android/app/src/main/assets/public/
node_modules/
.pnpm-store/
build/
build-server/
.svelte-kit/
.next/
# Rust/Tauri
*target/
src-tauri/binaries/
# iOS
ios/App/App/public
ios/DerivedData
@@ -67,7 +70,6 @@ GoogleService-Info.plist
.roo
.idea/
.vscode/
.claude/
# OS generated
.DS_Store
-57
View File
@@ -1,62 +1,5 @@
# Changelog
# 1.8.0
* Fix relay badge overflow
* Suppress programmatic scroll when user is scrolling
* Fix vertical alignment of emoji and overflow buttons in shared event action row
* Use type=email for signup/login email inputs, validate password
* Improve toggle switch placement on settings screens
* Fix relay auth privacy toggle
* Improve field layout
* Add progress bar to signup flow
* Bundle emojis properly
* Rework hosting page
* Fix padding on pages on small screens
* Add richer link preview support
* Fix pasting into event summary
* Publish fewer join/claim requests
* Fix new messages not rendering in safari
* Avoid capturing stale cleanup function in chat
* Hide keyboard on app resume
* Add email rendering support
* Fix bunker login
* Fix undefined chat draft key
* Allow sharing to chat without a message
* Make sure to show date on calendar events when embedded
* Improve space search
# 1.7.4
* Fix safe area inset for FAB
# 1.7.3
* Add native share support for space invites
* Stop sending duplicate requests per room
* Add more robust thumbnail url generation
* Make space reordering discoverable with smoother drag animation
* Improve relay member list
* Add room mentions and clickable room/relay refs
* Support native clipboard image paste on mobile
* publish kind 9 quote after room content creation for cross-client interoperability
* Improve feed pagination logic and performance
* Support Aegis URL scheme for NIP-46 login
* Various UI and bug fixes
* Raise message size limit in chat
* Fix realtime updates for room members and admins
* Add video to calls
* Remove follow graph building
* Add start chat FAB
* Add drafts
* Redesign toast notifications
* Remove room/space leave indications
* Hide report badge for non-admin users
* Add polls
* Add search to recent activity page
* Fix notification badge on mobile nav
* Change audio devices in call
# 1.7.2
* Fix race condition in nip 46
+26 -25
View File
@@ -1,31 +1,32 @@
# Build and run the Flotilla web server.
#
# docker build -t flotilla .
# docker run -p 3000:3000 flotilla
#
# Pass --build-arg VITE_BUILD_HASH=$(git rev-parse --short HEAD) to stamp the build.
# A .env in the build context is picked up by build.sh for branding config.
# Stage 1: Build
# Uses .env from build context for config (logo, branding, etc.)
# Optional: docker build --build-arg VITE_BUILD_HASH=$(git rev-parse --short HEAD) -t flotilla .
# https://pnpm.io/docker#example-3-build-on-cicd
FROM node:24-slim AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
FROM node:20-bookworm AS builder
RUN apt-get update && apt-get install -y --no-install-recommends curl
RUN npm install -g pnpm@latest
WORKDIR /app
ENV NODE_OPTIONS=--max_old_space_size=16384
COPY package.json pnpm-lock.yaml ./
RUN pnpm i --frozen-lockfile
COPY . .
ARG VITE_BUILD_HASH
RUN pnpm run build
RUN pnpm run build:server
RUN pnpm i
# Copy everything (including .env when present) - build.sh will source it
COPY . .
ARG VITE_BUILD_HASH
ENV VITE_BUILD_HASH=${VITE_BUILD_HASH}
ENV NODE_OPTIONS=--max_old_space_size=16384
RUN pnpm run build
FROM node:20-alpine
FROM node:24-slim AS production
ENV NODE_ENV=production
WORKDIR /app
COPY --from=builder /app/build /app/build
COPY --from=builder /app/build-server/server.js /app/server.js
EXPOSE 3000
USER node
CMD ["node", "server.js"]
# Copy only the built output - no source, no .env, no dev deps
COPY --from=builder /app/build ./build
CMD ["npx", "serve", "-s", "build"]
+3 -3
View File
@@ -31,18 +31,18 @@ To run your own Flotilla, it's as simple as:
```sh
pnpm install
pnpm run build
pnpm run start
npx serve -s build
```
Or, if you prefer to use a container:
```sh
docker run -d -p 3000:3000 gitea.coracle.social/coracle/flotilla:latest
podman run -d -p 3000:3000 ghcr.io/coracle-social/flotilla:latest
```
Alternatively, you can copy the build files into a directory of your choice and serve it yourself:
```sh
mkdir ./mount
docker run -v ./mount:/app/mount gitea.coracle.social/coracle/flotilla:latest bash -c 'cp -r build/* mount'
podman run -v ./mount:/app/mount ghcr.io/coracle-social/flotilla:latest bash -c 'cp -r build/* mount'
```
+2 -2
View File
@@ -8,8 +8,8 @@ android {
applicationId "social.flotilla"
minSdk rootProject.ext.minSdkVersion
targetSdk rootProject.ext.targetSdkVersion
versionCode 47
versionName "1.8.0"
versionCode 44
versionName "1.7.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
-2
View File
@@ -12,12 +12,10 @@ dependencies {
implementation project(':aparajita-capacitor-secure-storage')
implementation project(':capacitor-community-safe-area')
implementation project(':capacitor-app')
implementation project(':capacitor-clipboard')
implementation project(':capacitor-filesystem')
implementation project(':capacitor-keyboard')
implementation project(':capacitor-preferences')
implementation project(':capacitor-push-notifications')
implementation project(':capacitor-share')
implementation project(':capawesome-capacitor-android-dark-mode-support')
implementation project(':capawesome-capacitor-badge')
implementation project(':nostr-signer-capacitor-plugin')
@@ -7,7 +7,6 @@ import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.OutOfQuotaPolicy
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import com.getcapacitor.JSObject
@@ -77,7 +76,6 @@ class AndroidPushFallbackPlugin : Plugin() {
val immediate = OneTimeWorkRequest.Builder(AndroidPushFallbackWorker::class.java)
.setConstraints(constraints)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()
workManager.enqueueUniquePeriodicWork(
@@ -43,7 +43,7 @@ class AndroidPushFallbackWorker(context: Context, params: WorkerParameters) : Wo
private const val TAG = "PushFallback"
private const val CHANNEL_ID = "flotilla_fallback"
private const val CURSOR_PREFIX = "androidPushFallback.cursor."
private const val SOCKET_TIMEOUT_SECONDS = 30L
private const val SOCKET_TIMEOUT_SECONDS = 20L
private const val REJECTED = "__REJECTED__"
private const val KIND_RELAY_AUTH = 22242
private const val KIND_NIP46_RPC = 24133
@@ -72,8 +72,6 @@ class AndroidPushFallbackWorker(context: Context, params: WorkerParameters) : Wo
}
override fun doWork(): Result {
Log.i(TAG, "doWork() started")
if (isAppInForeground()) {
return Result.success()
}
@@ -90,7 +88,7 @@ class AndroidPushFallbackWorker(context: Context, params: WorkerParameters) : Wo
val activeSince = state.optLong("activeSince", 0L)
val seen = mutableSetOf<String>()
val newEvents = mutableListOf<Pair<String, JSONObject>>()
var latestPair: Pair<String, JSONObject>? = null
for (sub in subscriptions) {
val cursorKey = CURSOR_PREFIX + sub.relay + ":" + sub.key
@@ -104,19 +102,23 @@ class AndroidPushFallbackWorker(context: Context, params: WorkerParameters) : Wo
for (event in result.events) {
val id = event.optString("id", "")
if (id.isNotEmpty() && seen.add(id)) {
newEvents.add(Pair(sub.relay, event))
val createdAt = event.optLong("created_at", 0L)
if (latestPair == null || createdAt > latestPair!!.second.optLong("created_at", 0L)) {
latestPair = Pair(sub.relay, event)
}
}
}
}
for ((relay, event) in newEvents) {
if (latestPair != null) {
val (relay, event) = latestPair!!
postNotification(relay, event)
}
return Result.success()
} catch (e: Exception) {
Log.e(TAG, "Worker failed", e)
return Result.retry()
return Result.success()
} finally {
pool.closeAll()
client.dispatcher.executorService.shutdown()
@@ -212,8 +214,7 @@ class AndroidPushFallbackWorker(context: Context, params: WorkerParameters) : Wo
.setContentIntent(pendingIntent)
.build()
val notificationId = id.hashCode().let { if (it == 0) 1 else it }
NotificationManagerCompat.from(context).notify(notificationId, notification)
NotificationManagerCompat.from(context).notify(1, notification)
}
private fun matchesFilter(filter: JSONObject, event: JSONObject): Boolean {
-6
View File
@@ -11,9 +11,6 @@ project(':capacitor-community-safe-area').projectDir = new File('../node_modules
include ':capacitor-app'
project(':capacitor-app').projectDir = new File('../node_modules/.pnpm/@capacitor+app@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/app/android')
include ':capacitor-clipboard'
project(':capacitor-clipboard').projectDir = new File('../node_modules/.pnpm/@capacitor+clipboard@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/clipboard/android')
include ':capacitor-filesystem'
project(':capacitor-filesystem').projectDir = new File('../node_modules/.pnpm/@capacitor+filesystem@8.1.0_@capacitor+core@8.0.1/node_modules/@capacitor/filesystem/android')
@@ -26,9 +23,6 @@ project(':capacitor-preferences').projectDir = new File('../node_modules/.pnpm/@
include ':capacitor-push-notifications'
project(':capacitor-push-notifications').projectDir = new File('../node_modules/.pnpm/@capacitor+push-notifications@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/push-notifications/android')
include ':capacitor-share'
project(':capacitor-share').projectDir = new File('../node_modules/.pnpm/@capacitor+share@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/share/android')
include ':capawesome-capacitor-android-dark-mode-support'
project(':capawesome-capacitor-android-dark-mode-support').projectDir = new File('../node_modules/.pnpm/@capawesome+capacitor-android-dark-mode-support@8.0.0_@capacitor+core@8.0.1/node_modules/@capawesome/capacitor-android-dark-mode-support/android')
+11 -29
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
@@ -131,9 +131,8 @@
504EC2FC1FED79650016851F /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 920;
LastUpgradeCheck = 2630;
LastUpgradeCheck = 920;
TargetAttributes = {
504EC3031FED79650016851F = {
CreatedOnToolsVersion = 9.2;
@@ -258,7 +257,6 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -266,10 +264,8 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -279,10 +275,8 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = S26U9DYW3A;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -301,7 +295,6 @@
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
@@ -321,7 +314,6 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -329,10 +321,8 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -342,10 +332,8 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = S26U9DYW3A;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -357,9 +345,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -372,16 +358,14 @@
CODE_SIGN_ENTITLEMENTS = "Flotilla Chat.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 38;
CURRENT_PROJECT_VERSION = 35;
DEVELOPMENT_TEAM = S26U9DYW3A;
INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.7.2;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = social.flotilla;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -401,16 +385,14 @@
CODE_SIGN_ENTITLEMENTS = "Flotilla Chat.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 38;
CURRENT_PROJECT_VERSION = 35;
DEVELOPMENT_TEAM = S26U9DYW3A;
INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.7.2;
PRODUCT_BUNDLE_IDENTIFIER = social.flotilla;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
-2
View File
@@ -14,12 +14,10 @@ def capacitor_pods
pod 'AparajitaCapacitorSecureStorage', :path => '../../node_modules/.pnpm/@aparajita+capacitor-secure-storage@8.0.0/node_modules/@aparajita/capacitor-secure-storage'
pod 'CapacitorCommunitySafeArea', :path => '../../node_modules/.pnpm/@capacitor-community+safe-area@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor-community/safe-area'
pod 'CapacitorApp', :path => '../../node_modules/.pnpm/@capacitor+app@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/app'
pod 'CapacitorClipboard', :path => '../../node_modules/.pnpm/@capacitor+clipboard@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/clipboard'
pod 'CapacitorFilesystem', :path => '../../node_modules/.pnpm/@capacitor+filesystem@8.1.0_@capacitor+core@8.0.1/node_modules/@capacitor/filesystem'
pod 'CapacitorKeyboard', :path => '../../node_modules/.pnpm/@capacitor+keyboard@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/keyboard'
pod 'CapacitorPreferences', :path => '../../node_modules/.pnpm/@capacitor+preferences@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/preferences'
pod 'CapacitorPushNotifications', :path => '../../node_modules/.pnpm/@capacitor+push-notifications@8.0.0_@capacitor+core@8.0.1/node_modules/@capacitor/push-notifications'
pod 'CapacitorShare', :path => '../../node_modules/.pnpm/@capacitor+share@8.0.1_@capacitor+core@8.0.1/node_modules/@capacitor/share'
pod 'CapawesomeCapacitorBadge', :path => '../../node_modules/.pnpm/@capawesome+capacitor-badge@8.0.0_@capacitor+core@8.0.1/node_modules/@capawesome/capacitor-badge'
pod 'NostrSignerCapacitorPlugin', :path => '../../node_modules/.pnpm/nostr-signer-capacitor-plugin@https+++codeload.github.com+coracle-social+nostr-signer-c_2704ecccfd05fcfb1ad8852744422b7c/node_modules/nostr-signer-capacitor-plugin'
end
+18 -23
View File
@@ -1,13 +1,15 @@
{
"name": "flotilla",
"version": "1.8.0",
"version": "1.7.2",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "./build.sh",
"build:server": "vite build --config vite.config.server.ts",
"start": "node server.js",
"release:android": "./build.sh && cap build android --androidreleasetype APK --signing-type apksigner",
"tauri:dev": "tauri dev",
"tauri:build": "tauri build",
"tauri:info": "tauri info",
"tauri:icons": "tauri icon assets/logo.png --output src-tauri/icons",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check src && eslint src",
@@ -21,6 +23,7 @@
"@sveltejs/kit": "^2.50.1",
"@sveltejs/vite-plugin-svelte": "^4.0.4",
"@tailwindcss/postcss": "^4.2.2",
"@tauri-apps/cli": "^2.9.6",
"@types/eslint": "^9.6.1",
"autoprefixer": "^10.4.23",
"classnames": "^2.5.1",
@@ -45,48 +48,41 @@
"@capacitor/android": "^8.0.1",
"@capacitor/app": "^8.0.0",
"@capacitor/cli": "^8.0.1",
"@capacitor/clipboard": "^8.0.1",
"@capacitor/core": "^8.0.1",
"@capacitor/filesystem": "^8.1.0",
"@capacitor/ios": "^8.0.1",
"@capacitor/keyboard": "^8.0.0",
"@capacitor/preferences": "^8.0.0",
"@capacitor/push-notifications": "^8.0.0",
"@capacitor/share": "^8.0.1",
"@capawesome/capacitor-android-dark-mode-support": "^8.0.0",
"@capawesome/capacitor-badge": "^8.0.0",
"@getalby/lightning-tools": "^6.1.0",
"@getalby/sdk": "^5.1.2",
"@hono/node-server": "^2.0.0",
"@noble/curves": "^1.9.7",
"@pomade/core": "^0.2.3",
"@pomade/core": "^0.2.2",
"@poppanator/sveltekit-svg": "^4.2.1",
"@sveltejs/adapter-static": "^3.0.10",
"@tiptap/core": "^2.27.2",
"@tiptap/pm": "^2.27.2",
"@types/qrcode": "^1.5.6",
"@types/throttle-debounce": "^5.0.2",
"@vite-pwa/assets-generator": "^0.2.6",
"@vite-pwa/sveltekit": "^0.6.8",
"@welshman/app": "^0.8.15",
"@welshman/content": "^0.8.15",
"@welshman/editor": "^0.8.15",
"@welshman/feeds": "^0.8.15",
"@welshman/lib": "^0.8.15",
"@welshman/net": "^0.8.15",
"@welshman/router": "^0.8.15",
"@welshman/signer": "^0.8.15",
"@welshman/store": "^0.8.15",
"@welshman/util": "^0.8.15",
"cheerio": "^1.2.0",
"@welshman/app": "^0.8.12",
"@welshman/content": "^0.8.12",
"@welshman/editor": "^0.8.12",
"@welshman/feeds": "^0.8.12",
"@welshman/lib": "^0.8.12",
"@welshman/net": "^0.8.12",
"@welshman/router": "^0.8.12",
"@welshman/signer": "^0.8.12",
"@welshman/store": "^0.8.12",
"@welshman/util": "^0.8.12",
"compressorjs-next": "^1.1.2",
"daisyui": "^5.5.19",
"date-picker-svelte": "^2.17.0",
"dotenv": "^16.6.1",
"emoji-picker-element": "^1.28.1",
"emoji-picker-element-data": "^1.8.0",
"fuse.js": "^7.1.0",
"hono": "^4.12.15",
"husky": "^9.1.7",
"idb": "^8.0.3",
"livekit-client": "^2.17.2",
@@ -109,6 +105,5 @@
"overrides": {
"sharp": "0.35.0-rc.0"
}
},
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
}
}
+245 -295
View File
@@ -26,9 +26,6 @@ importers:
'@capacitor/cli':
specifier: ^8.0.1
version: 8.0.1
'@capacitor/clipboard':
specifier: ^8.0.1
version: 8.0.1(@capacitor/core@8.0.1)
'@capacitor/core':
specifier: ^8.0.1
version: 8.0.1
@@ -47,9 +44,6 @@ importers:
'@capacitor/push-notifications':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.1)
'@capacitor/share':
specifier: ^8.0.1
version: 8.0.1(@capacitor/core@8.0.1)
'@capawesome/capacitor-android-dark-mode-support':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.1)
@@ -62,15 +56,12 @@ importers:
'@getalby/sdk':
specifier: ^5.1.2
version: 5.1.2(typescript@5.9.3)
'@hono/node-server':
specifier: ^2.0.0
version: 2.0.0(hono@4.12.15)
'@noble/curves':
specifier: ^1.9.7
version: 1.9.7
'@pomade/core':
specifier: ^0.2.3
version: 0.2.3(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))
specifier: ^0.2.2
version: 0.2.2(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))
'@poppanator/sveltekit-svg':
specifier: ^4.2.1
version: 4.2.1(rollup@2.80.0)(svelte@5.48.0)(svgo@3.3.2)(vite@5.4.21(@types/node@25.0.10)(lightningcss@1.32.0)(terser@5.46.0))
@@ -80,9 +71,6 @@ importers:
'@tiptap/core':
specifier: ^2.27.2
version: 2.27.2(@tiptap/pm@2.27.2)
'@tiptap/pm':
specifier: ^2.27.2
version: 2.27.2
'@types/qrcode':
specifier: ^1.5.6
version: 1.5.6
@@ -96,38 +84,35 @@ importers:
specifier: ^0.6.8
version: 0.6.8(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.48.0)(vite@5.4.21(@types/node@25.0.10)(lightningcss@1.32.0)(terser@5.46.0)))(svelte@5.48.0)(typescript@5.9.3)(vite@5.4.21(@types/node@25.0.10)(lightningcss@1.32.0)(terser@5.46.0)))(@vite-pwa/assets-generator@0.2.6)(vite-plugin-pwa@0.21.2(@vite-pwa/assets-generator@0.2.6)(vite@5.4.21(@types/node@25.0.10)(lightningcss@1.32.0)(terser@5.46.0))(workbox-build@7.3.0)(workbox-window@7.3.0))
'@welshman/app':
specifier: ^0.8.15
version: 0.8.15(21e35c724ddffaa65c2a5f61f6a711d8)
specifier: ^0.8.12
version: 0.8.12(3074ef6691f94dc03952d8dbc98013a7)
'@welshman/content':
specifier: ^0.8.15
version: 0.8.15(nostr-tools@2.20.0(typescript@5.9.3))
specifier: ^0.8.12
version: 0.8.12(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/editor':
specifier: ^0.8.15
version: 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-editor@1.1.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/extension-image@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))(@tiptap/extension-link@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(linkifyjs@4.3.2)(nostr-tools@2.20.0(typescript@5.9.3))(prosemirror-markdown@1.13.3)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(tiptap-markdown@0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))))(nostr-tools@2.20.0(typescript@5.9.3))
specifier: ^0.8.12
version: 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-editor@1.1.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/extension-image@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))(@tiptap/extension-link@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(linkifyjs@4.3.2)(nostr-tools@2.20.0(typescript@5.9.3))(prosemirror-markdown@1.13.3)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(tiptap-markdown@0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/feeds':
specifier: ^0.8.15
version: 0.8.15(7168f3004fe8b7d93325d3fd44825488)
specifier: ^0.8.12
version: 0.8.12(d5b74f0c83250e052e0b96f7ff5804e8)
'@welshman/lib':
specifier: ^0.8.15
version: 0.8.15
specifier: ^0.8.12
version: 0.8.12
'@welshman/net':
specifier: ^0.8.15
version: 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
specifier: ^0.8.12
version: 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/router':
specifier: ^0.8.15
version: 0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))
specifier: ^0.8.12
version: 0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))
'@welshman/signer':
specifier: ^0.8.15
version: 0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
specifier: ^0.8.12
version: 0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/store':
specifier: ^0.8.15
version: 0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)
specifier: ^0.8.12
version: 0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)
'@welshman/util':
specifier: ^0.8.15
version: 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
cheerio:
specifier: ^1.2.0
version: 1.2.0
specifier: ^0.8.12
version: 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
compressorjs-next:
specifier: ^1.1.2
version: 1.1.2
@@ -143,15 +128,9 @@ importers:
emoji-picker-element:
specifier: ^1.28.1
version: 1.28.1
emoji-picker-element-data:
specifier: ^1.8.0
version: 1.8.0
fuse.js:
specifier: ^7.1.0
version: 7.1.0
hono:
specifier: ^4.12.15
version: 4.12.15
husky:
specifier: ^9.1.7
version: 9.1.7
@@ -163,7 +142,7 @@ importers:
version: 2.17.3(@types/dom-mediacapture-record@1.0.22)
nostr-signer-capacitor-plugin:
specifier: github:coracle-social/nostr-signer-capacitor-plugin#main
version: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1)
version: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1)
nostr-tools:
specifier: ^2.19.4
version: 2.20.0(typescript@5.9.3)
@@ -198,6 +177,9 @@ importers:
'@tailwindcss/postcss':
specifier: ^4.2.2
version: 4.2.2
'@tauri-apps/cli':
specifier: ^2.9.6
version: 2.10.0
'@types/eslint':
specifier: ^9.6.1
version: 9.6.1
@@ -809,11 +791,6 @@ packages:
engines: {node: '>=22.0.0'}
hasBin: true
'@capacitor/clipboard@8.0.1':
resolution: {integrity: sha512-iOlbTi8MojKyLnYE+M27priXid7vHd0PlDwyHohPzkuQ8Rkp6q7ykwZmPEUD+OnU/Ink7Qw/pUOfKgraKmA6Eg==}
peerDependencies:
'@capacitor/core': '>=8.0.0'
'@capacitor/core@8.0.1':
resolution: {integrity: sha512-5UqSWxGMp/B8KhYu7rAijqNtYslhcLh+TrbfU48PfdMDsPfaU/VY48sMNzC22xL8BmoFoql/3SKyP+pavTOvOA==}
@@ -850,11 +827,6 @@ packages:
peerDependencies:
'@capacitor/core': '>=8.0.0'
'@capacitor/share@8.0.1':
resolution: {integrity: sha512-3cSBKBCJVon54rKDROP2rqGyeGks4pBh9TbaEk9S375Kbek/ZHe72N50zIa0Vn9Eac/SuhwgehO/mmA4CsUOiw==}
peerDependencies:
'@capacitor/core': '>=8.0.0'
'@capacitor/synapse@1.0.4':
resolution: {integrity: sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==}
@@ -1105,12 +1077,6 @@ packages:
resolution: {integrity: sha512-yUF9LhuvdIFOwjV1aG0ryzfwDiGBFk/CRLkRvrrM9dsE38SUjKsf1FDga5jxsKMu80nWcPZR9TiGGASWedoYPA==}
engines: {node: '>=14'}
'@hono/node-server@2.0.0':
resolution: {integrity: sha512-n3GfHwwCvHCkGmOwKfxUPOlbfzuO64Sbc5XC4NGPIXxkuOnJrdgExdRKmHfF924r914WRJPT397GdqLvdYTeyQ==}
engines: {node: '>=20'}
peerDependencies:
hono: ^4
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
@@ -1461,9 +1427,9 @@ packages:
'@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
'@pomade/core@0.2.3':
resolution: {integrity: sha512-36+abWfMH1Mif9FjBO7xICCkGZE4IqQpy7Csxlauyt0bhYQ9GsB07LqK5Qm3GgEHNwF9rFXdSZawkM+E6BeIfg==}
version: 0.2.3
'@pomade/core@0.2.2':
resolution: {integrity: sha512-FoilLsO0gVjiKMW3LV63pmXU7x3gh8YVGVulyR6QJr4h47XrsBg8vPkZtKWr4+sH3sW31e2tNIPUb3ptiuhrMA==}
version: 0.2.2
engines: {node: '>=12.0.0'}
peerDependencies:
'@frostr/bifrost': ^1.0.7
@@ -1837,6 +1803,82 @@ packages:
'@tailwindcss/postcss@4.2.2':
resolution: {integrity: sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ==}
'@tauri-apps/cli-darwin-arm64@2.10.0':
resolution: {integrity: sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@tauri-apps/cli-darwin-x64@2.10.0':
resolution: {integrity: sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@tauri-apps/cli-linux-arm-gnueabihf@2.10.0':
resolution: {integrity: sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@tauri-apps/cli-linux-arm64-gnu@2.10.0':
resolution: {integrity: sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@tauri-apps/cli-linux-arm64-musl@2.10.0':
resolution: {integrity: sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@tauri-apps/cli-linux-riscv64-gnu@2.10.0':
resolution: {integrity: sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@tauri-apps/cli-linux-x64-gnu@2.10.0':
resolution: {integrity: sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@tauri-apps/cli-linux-x64-musl@2.10.0':
resolution: {integrity: sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@tauri-apps/cli-win32-arm64-msvc@2.10.0':
resolution: {integrity: sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@tauri-apps/cli-win32-ia32-msvc@2.10.0':
resolution: {integrity: sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
'@tauri-apps/cli-win32-x64-msvc@2.10.0':
resolution: {integrity: sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@tauri-apps/cli@2.10.0':
resolution: {integrity: sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q==}
engines: {node: '>= 10'}
hasBin: true
'@tiptap/core@2.27.2':
resolution: {integrity: sha512-ABL1N6eoxzDzC1bYvkMbvyexHacszsKdVPYqhl5GwHLOvpZcv9VE9QaKwDILTyz5voCA0lGcAAXZp+qnXOk5lQ==}
peerDependencies:
@@ -2089,83 +2131,83 @@ packages:
'@vite-pwa/assets-generator':
optional: true
'@welshman/app@0.8.15':
resolution: {integrity: sha512-GDo6w+UI/ldnh47c5IEDYWw8nbiyhnH4abJNy/q/jLBUwJ9SuiJ7GVVvhZ+t4XEo5NEMq+y4OLZs08+abf85MQ==}
'@welshman/app@0.8.12':
resolution: {integrity: sha512-kRp+AVzn4i3FvZmdlyMknFUAb/5SnUz9A/cFKkDqWHsd+N3PbNcL2ZOlV9v5NI77GtsDF2ez6PEQfsZxWvkS/g==}
peerDependencies:
'@pomade/core': ^0.2.1
'@welshman/feeds': 0.8.15
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15
'@welshman/router': 0.8.15
'@welshman/signer': 0.8.15
'@welshman/store': 0.8.15
'@welshman/util': 0.8.15
'@welshman/feeds': 0.8.12
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12
'@welshman/router': 0.8.12
'@welshman/signer': 0.8.12
'@welshman/store': 0.8.12
'@welshman/util': 0.8.12
svelte: ^4.0.0 || ^5.0.0
'@welshman/content@0.8.15':
resolution: {integrity: sha512-5qe+6Es1r62HkVdeHJPsWkOpLjhdxBTtw3d4+Or1JXl8BgpUE2JV7e+5HQQqnPRVHt3nt14YPt0oirar5p1Fvg==}
'@welshman/content@0.8.12':
resolution: {integrity: sha512-hviVTXdyGf04Xq7mGo/82fq6lnbyuUYOGPkf8pJqPkfGh0f3i9nKof6gkzPvjZeEYSczneI2GpLIxkaZ3w1/tw==}
peerDependencies:
nostr-tools: ^2.19.4
'@welshman/editor@0.8.15':
resolution: {integrity: sha512-lqTLQGf54yPioBn2KQsF7F5ExWM6Co31wgGaUAhCSeUGiTzUQgMEut4/N8VB1rFZ0wqU6zyPG5jgeuhFhRJWSw==}
'@welshman/editor@0.8.12':
resolution: {integrity: sha512-CEXszH6pfM1kZHU9WnB6Z97YlxEOtgao6R3hhnBL/kRXy2tUTLpmFWyMONg2vu8Uzxtwz665eZhucLsju60U6w==}
peerDependencies:
'@welshman/lib': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/util': 0.8.12
nostr-editor: ^1.1.1
nostr-tools: ^2.19.4
'@welshman/feeds@0.8.15':
resolution: {integrity: sha512-xIQDKdV6uLxOz5qJUbc/2HC6qnikgH1GPoHQwBpwKH7Lga6a7IGLOR6kvghUaPpulKcuF4MxG9gmvEHqgsQkJw==}
'@welshman/feeds@0.8.12':
resolution: {integrity: sha512-Dp/063qdrbe096z6IpIneazsqscfzSwsg09ZNHB6c3OsVb6iLEXLe7mEpATGcRsZ8memuFNLVLIP51eVkBqPcQ==}
peerDependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15
'@welshman/router': 0.8.15
'@welshman/signer': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12
'@welshman/router': 0.8.12
'@welshman/signer': 0.8.12
'@welshman/util': 0.8.12
'@welshman/lib@0.8.15':
resolution: {integrity: sha512-d7o6WUSVYXOstpWTqOBDfkSyr3GOBm/UMbgFx3RXCxzib0cWm7z0w1oLWvy1N7fjHc/Jp65G2KRpT6//B9yAww==}
'@welshman/lib@0.8.12':
resolution: {integrity: sha512-7Y1GjAcABquWF47A1Jni5JdP+k0GH2yRmEbVhIU+0R0TubCwPAKS38J2LTvtuE9CJMX6hPS9IKEZS6qTOAaVuw==}
engines: {node: '>=12.0.0'}
'@welshman/net@0.8.15':
resolution: {integrity: sha512-AeJ/Vy7T6ruf1mjzzEUdH+aX5JriQKBzRn1zWZ4l8VEgxwc4w2bVte9a6aPnNJWc7JZT8ws8z+wOi4ECb6NPNA==}
'@welshman/net@0.8.12':
resolution: {integrity: sha512-Ba71jwb8BBwUfPPtWHKYLB0HqeDYK64oqwxfo5bYldtPfGYrlD+a7lHFSZvNyOhvyXygCaIMnaye1QxWAHP8ng==}
peerDependencies:
'@welshman/lib': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/util': 0.8.12
'@welshman/router@0.8.15':
resolution: {integrity: sha512-3lxcCYMaPX0gFaoM1GjBRvXr4UrnPA3o/mBII2Zm3gJeFuXN3XG+REwIN6QNhvTB7syTCTwx+dRdHgvqHl9N6g==}
'@welshman/router@0.8.12':
resolution: {integrity: sha512-Rr7ryBNTvTvjoLsDRMKPuoNJbBv2MgyqN2338p4vVhPMK6MOGM3Nx1og0LpHDGiLlCFuPM8RpParpIWfNnWbKw==}
peerDependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12
'@welshman/util': 0.8.12
'@welshman/signer@0.8.15':
resolution: {integrity: sha512-Y96XZtsCHz8h7NK28sSi3CX+8lGG6WhLyVNyhlEhfypAxxx8Zpfr4GlSPApvp4tvm1//YfDtXHIIZTPXbmnqvA==}
version: 0.8.15
'@welshman/signer@0.8.12':
resolution: {integrity: sha512-eO4mw2QOR2d2oCS4zgptkCgjC1s8X+1vNnXfWDbtlEwhk7PD4ySSCkpNVMeElq+uluLOugmKvgDc4gfnIH3p2A==}
version: 0.8.12
peerDependencies:
'@noble/curves': ^1.9.7
'@noble/hashes': ^2.0.1
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12
'@welshman/util': 0.8.12
nostr-signer-capacitor-plugin: '*'
nostr-tools: ^2.19.4
'@welshman/store@0.8.15':
resolution: {integrity: sha512-3rQVhAsQ1z5tcUzkJPkzVp3iBkMrUKVoBi07AYefqlhRoddhwB2pDBVhdZYoP2kl9wVPZlPV58vlD6BTo6TEwA==}
'@welshman/store@0.8.12':
resolution: {integrity: sha512-3IUzPRMMVF6Pcw3DaKkfJ4S6bYzVtk6Ze3FnaHs1xJIxkQj9GyBO9VreiovULPW0djsnrP5+1UEN4mKZsG3hXg==}
peerDependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15
'@welshman/util': 0.8.15
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12
'@welshman/util': 0.8.12
svelte: ^4.0.0 || ^5.0.0
'@welshman/util@0.8.15':
resolution: {integrity: sha512-zeNWMyOtIpOqj9/hBAT8qWvnp5w/IyrcT7CmDKLkWt6NU6ZoZ3pF5duTwtOYZqcftYJaHXgohOt0RsHVPR3M7w==}
'@welshman/util@0.8.12':
resolution: {integrity: sha512-lgftFt2moXZdN5fuL0RoAnAARV0n0d2+Q56gt7KrBSevjoCbtJgBVX5idvxL5PCEfh81veovJtty6eHxrhQv5A==}
peerDependencies:
'@noble/curves': ^1.9.7
'@welshman/lib': 0.8.15
'@welshman/lib': 0.8.12
nostr-tools: ^2.19.4
'@xml-tools/parser@1.0.11':
@@ -2404,13 +2446,6 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
cheerio@1.2.0:
resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==}
engines: {node: '>=20.18.1'}
chevrotain@7.1.1:
resolution: {integrity: sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==}
@@ -2770,18 +2805,12 @@ packages:
resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==}
engines: {node: '>= 0.4.0'}
emoji-picker-element-data@1.8.0:
resolution: {integrity: sha512-VfRuRJNEDLS1JKlNS4olaqhjX5S1nnZ+ZHG73b/dV8QeZyi0yPruTPEE72EmF6XO3k/9hj3lybMIYMOYXb/57A==}
emoji-picker-element@1.28.1:
resolution: {integrity: sha512-8c64IPish2PWoV9oYCo2pvuPHwIv+uK9bO0dfpPyMupDAvaWL9ZvYhWNTAR+2sx7BhfRjciImqP6CIUgNX+DMg==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
encoding-sniffer@0.2.1:
resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==}
enhanced-resolve@5.20.1:
resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==}
engines: {node: '>=10.13.0'}
@@ -2793,14 +2822,6 @@ packages:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
entities@7.0.1:
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
engines: {node: '>=0.12'}
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -3194,10 +3215,6 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
hono@4.12.15:
resolution: {integrity: sha512-qM0jDhFEaCBb4TxoW7f53Qrpv9RBiayUHo0S52JudprkhvpjIrGoU1mnnr29Fvd1U335ZFPZQY1wlkqgfGXyLg==}
engines: {node: '>=16.9.0'}
hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@@ -3205,9 +3222,6 @@ packages:
resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
engines: {node: '>=10'}
htmlparser2@10.1.0:
resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
husky@9.1.7:
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
engines: {node: '>=18'}
@@ -3216,10 +3230,6 @@ packages:
ico-endec@0.1.6:
resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
idb@7.1.1:
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
@@ -3869,8 +3879,8 @@ packages:
prosemirror-view: ^1.39.3
tiptap-markdown: ^0.8.10
nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47:
resolution: {tarball: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47}
nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51:
resolution: {tarball: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51}
version: 0.0.5
peerDependencies:
'@capacitor/core': ^8.0.0
@@ -3986,15 +3996,6 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
parse5-htmlparser2-tree-adapter@7.1.0:
resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==}
parse5-parser-stream@7.1.2:
resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==}
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
@@ -4436,9 +4437,6 @@ packages:
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
engines: {node: '>= 0.4'}
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sax@1.1.4:
resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==}
@@ -4874,10 +4872,6 @@ packages:
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
undici@7.25.0:
resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==}
engines: {node: '>=20.18.1'}
unicode-canonical-property-names-ecmascript@2.0.1:
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
engines: {node: '>=4'}
@@ -4996,15 +4990,6 @@ packages:
resolution: {integrity: sha512-5ZZY1+lGq8LEKuDlg9M2RPJHlH3R7OVwyHqMcUsLKCgd9Wvf+QrFTCItkXXYPmrJn8H6gRLXbSgxLLdexiqHxw==}
engines: {node: '>=6.0.0', npm: '>=3.10.0'}
whatwg-encoding@3.1.1:
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
engines: {node: '>=18'}
deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
whatwg-mimetype@4.0.0:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
engines: {node: '>=18'}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
@@ -5984,10 +5969,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@capacitor/clipboard@8.0.1(@capacitor/core@8.0.1)':
dependencies:
'@capacitor/core': 8.0.1
'@capacitor/core@8.0.1':
dependencies:
tslib: 2.8.1
@@ -6025,10 +6006,6 @@ snapshots:
dependencies:
'@capacitor/core': 8.0.1
'@capacitor/share@8.0.1(@capacitor/core@8.0.1)':
dependencies:
'@capacitor/core': 8.0.1
'@capacitor/synapse@1.0.4': {}
'@capawesome/capacitor-android-dark-mode-support@8.0.0(@capacitor/core@8.0.1)':
@@ -6224,10 +6201,6 @@ snapshots:
transitivePeerDependencies:
- typescript
'@hono/node-server@2.0.0(hono@4.12.15)':
dependencies:
hono: 4.12.15
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.7':
@@ -6637,15 +6610,15 @@ snapshots:
'@polka/url@1.0.0-next.29': {}
'@pomade/core@0.2.3(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))':
'@pomade/core@0.2.2(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))':
dependencies:
'@frostr/bifrost': 1.0.7(typescript@5.9.3)
'@noble/hashes': 2.0.1
'@peculiar/x509': 1.14.3
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/signer': 0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/signer': 0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
cbor-x: 1.6.0
hash-wasm: 4.12.0
nostr-tools: 2.20.0(typescript@5.9.3)
@@ -6949,6 +6922,53 @@ snapshots:
postcss: 8.5.6
tailwindcss: 4.2.2
'@tauri-apps/cli-darwin-arm64@2.10.0':
optional: true
'@tauri-apps/cli-darwin-x64@2.10.0':
optional: true
'@tauri-apps/cli-linux-arm-gnueabihf@2.10.0':
optional: true
'@tauri-apps/cli-linux-arm64-gnu@2.10.0':
optional: true
'@tauri-apps/cli-linux-arm64-musl@2.10.0':
optional: true
'@tauri-apps/cli-linux-riscv64-gnu@2.10.0':
optional: true
'@tauri-apps/cli-linux-x64-gnu@2.10.0':
optional: true
'@tauri-apps/cli-linux-x64-musl@2.10.0':
optional: true
'@tauri-apps/cli-win32-arm64-msvc@2.10.0':
optional: true
'@tauri-apps/cli-win32-ia32-msvc@2.10.0':
optional: true
'@tauri-apps/cli-win32-x64-msvc@2.10.0':
optional: true
'@tauri-apps/cli@2.10.0':
optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 2.10.0
'@tauri-apps/cli-darwin-x64': 2.10.0
'@tauri-apps/cli-linux-arm-gnueabihf': 2.10.0
'@tauri-apps/cli-linux-arm64-gnu': 2.10.0
'@tauri-apps/cli-linux-arm64-musl': 2.10.0
'@tauri-apps/cli-linux-riscv64-gnu': 2.10.0
'@tauri-apps/cli-linux-x64-gnu': 2.10.0
'@tauri-apps/cli-linux-x64-musl': 2.10.0
'@tauri-apps/cli-win32-arm64-msvc': 2.10.0
'@tauri-apps/cli-win32-ia32-msvc': 2.10.0
'@tauri-apps/cli-win32-x64-msvc': 2.10.0
'@tiptap/core@2.27.2(@tiptap/pm@2.27.2)':
dependencies:
'@tiptap/pm': 2.27.2
@@ -7256,26 +7276,26 @@ snapshots:
optionalDependencies:
'@vite-pwa/assets-generator': 0.2.6
'@welshman/app@0.8.15(21e35c724ddffaa65c2a5f61f6a711d8)':
'@welshman/app@0.8.12(3074ef6691f94dc03952d8dbc98013a7)':
dependencies:
'@pomade/core': 0.2.3(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/feeds': 0.8.15(7168f3004fe8b7d93325d3fd44825488)
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/router': 0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))
'@welshman/signer': 0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/store': 0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@pomade/core': 0.2.2(@frostr/bifrost@1.0.7(typescript@5.9.3))(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/signer@0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3)))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/feeds': 0.8.12(d5b74f0c83250e052e0b96f7ff5804e8)
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/router': 0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))
'@welshman/signer': 0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/store': 0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
fuse.js: 7.1.0
svelte: 5.48.0
throttle-debounce: 5.0.2
'@welshman/content@0.8.15(nostr-tools@2.20.0(typescript@5.9.3))':
'@welshman/content@0.8.12(nostr-tools@2.20.0(typescript@5.9.3))':
dependencies:
'@braintree/sanitize-url': 7.1.1
nostr-tools: 2.20.0(typescript@5.9.3)
'@welshman/editor@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-editor@1.1.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/extension-image@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))(@tiptap/extension-link@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(linkifyjs@4.3.2)(nostr-tools@2.20.0(typescript@5.9.3))(prosemirror-markdown@1.13.3)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(tiptap-markdown@0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))))(nostr-tools@2.20.0(typescript@5.9.3))':
'@welshman/editor@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-editor@1.1.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/extension-image@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))(@tiptap/extension-link@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(linkifyjs@4.3.2)(nostr-tools@2.20.0(typescript@5.9.3))(prosemirror-markdown@1.13.3)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(tiptap-markdown@0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))))(nostr-tools@2.20.0(typescript@5.9.3))':
dependencies:
'@tiptap/core': 2.27.2(@tiptap/pm@2.27.2)
'@tiptap/extension-code': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
@@ -7290,64 +7310,64 @@ snapshots:
'@tiptap/extension-text': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
'@tiptap/pm': 2.27.2
'@tiptap/suggestion': 2.27.2(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)
'@welshman/lib': 0.8.15
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
nostr-editor: 1.1.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/extension-image@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))(@tiptap/extension-link@2.27.1(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2))(@tiptap/pm@2.27.2)(linkifyjs@4.3.2)(nostr-tools@2.20.0(typescript@5.9.3))(prosemirror-markdown@1.13.3)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(tiptap-markdown@0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2)))
nostr-tools: 2.20.0(typescript@5.9.3)
tippy.js: 6.3.7
'@welshman/feeds@0.8.15(7168f3004fe8b7d93325d3fd44825488)':
'@welshman/feeds@0.8.12(d5b74f0c83250e052e0b96f7ff5804e8)':
dependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/router': 0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))
'@welshman/signer': 0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/router': 0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))
'@welshman/signer': 0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
trava: 1.2.1
'@welshman/lib@0.8.15':
'@welshman/lib@0.8.12':
dependencies:
'@scure/base': 1.2.6
'@types/events': 3.0.3
events: 3.3.0
'@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)':
'@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)':
dependencies:
'@welshman/lib': 0.8.15
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
events: 3.3.0
isomorphic-ws: 5.0.0(ws@8.18.3)
transitivePeerDependencies:
- ws
'@welshman/router@0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))':
'@welshman/router@0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))':
dependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/signer@0.8.15(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))':
'@welshman/signer@0.8.12(@noble/curves@1.9.7)(@noble/hashes@2.0.1)(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1))(nostr-tools@2.20.0(typescript@5.9.3))':
dependencies:
'@noble/curves': 1.9.7
'@noble/hashes': 2.0.1
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
nostr-signer-capacitor-plugin: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1)
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
nostr-signer-capacitor-plugin: https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1)
nostr-tools: 2.20.0(typescript@5.9.3)
'@welshman/store@0.8.15(@welshman/lib@0.8.15)(@welshman/net@0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)':
'@welshman/store@0.8.12(@welshman/lib@0.8.12)(@welshman/net@0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3))(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(svelte@5.48.0)':
dependencies:
'@welshman/lib': 0.8.15
'@welshman/net': 0.8.15(@welshman/lib@0.8.15)(@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))
'@welshman/lib': 0.8.12
'@welshman/net': 0.8.12(@welshman/lib@0.8.12)(@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3)))(ws@8.18.3)
'@welshman/util': 0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))
svelte: 5.48.0
'@welshman/util@0.8.15(@noble/curves@1.9.7)(@welshman/lib@0.8.15)(nostr-tools@2.20.0(typescript@5.9.3))':
'@welshman/util@0.8.12(@noble/curves@1.9.7)(@welshman/lib@0.8.12)(nostr-tools@2.20.0(typescript@5.9.3))':
dependencies:
'@noble/curves': 1.9.7
'@types/ws': 8.18.1
'@welshman/lib': 0.8.15
'@welshman/lib': 0.8.12
js-base64: 3.7.8
nostr-tools: 2.20.0(typescript@5.9.3)
nostr-wasm: 0.1.0
@@ -7595,29 +7615,6 @@ snapshots:
ansi-styles: 4.3.0
supports-color: 7.2.0
cheerio-select@2.1.0:
dependencies:
boolbase: 1.0.0
css-select: 5.2.2
css-what: 6.2.2
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.2.2
cheerio@1.2.0:
dependencies:
cheerio-select: 2.1.0
dom-serializer: 2.0.0
domhandler: 5.0.3
domutils: 3.2.2
encoding-sniffer: 0.2.1
htmlparser2: 10.1.0
parse5: 7.3.0
parse5-htmlparser2-tree-adapter: 7.1.0
parse5-parser-stream: 7.1.2
undici: 7.25.0
whatwg-mimetype: 4.0.0
chevrotain@7.1.1:
dependencies:
regexp-to-ast: 0.5.0
@@ -8004,17 +8001,10 @@ snapshots:
dependencies:
sax: 1.1.4
emoji-picker-element-data@1.8.0: {}
emoji-picker-element@1.28.1: {}
emoji-regex@8.0.0: {}
encoding-sniffer@0.2.1:
dependencies:
iconv-lite: 0.6.3
whatwg-encoding: 3.1.1
enhanced-resolve@5.20.1:
dependencies:
graceful-fs: 4.2.11
@@ -8024,10 +8014,6 @@ snapshots:
entities@4.5.0: {}
entities@6.0.1: {}
entities@7.0.1: {}
env-paths@2.2.1: {}
env-paths@3.0.0: {}
@@ -8537,29 +8523,16 @@ snapshots:
he@1.2.0: {}
hono@4.12.15: {}
hosted-git-info@2.8.9: {}
hosted-git-info@4.1.0:
dependencies:
lru-cache: 6.0.0
htmlparser2@10.1.0:
dependencies:
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.2.2
entities: 7.0.1
husky@9.1.7: {}
ico-endec@0.1.6: {}
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
idb@7.1.1: {}
idb@8.0.3: {}
@@ -9130,7 +9103,7 @@ snapshots:
prosemirror-view: 1.41.5
tiptap-markdown: 0.8.10(@tiptap/core@2.27.2(@tiptap/pm@2.27.2))
nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/436adec9ed1e71569748cd56aa697f361e7a8d47(@capacitor/core@8.0.1):
nostr-signer-capacitor-plugin@https://codeload.github.com/coracle-social/nostr-signer-capacitor-plugin/tar.gz/be4bb90a1a15c8eec0934f2f66ce9e82ecc72d51(@capacitor/core@8.0.1):
dependencies:
'@capacitor/core': 8.0.1
@@ -9266,19 +9239,6 @@ snapshots:
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
parse5-htmlparser2-tree-adapter@7.1.0:
dependencies:
domhandler: 5.0.3
parse5: 7.3.0
parse5-parser-stream@7.1.2:
dependencies:
parse5: 7.3.0
parse5@7.3.0:
dependencies:
entities: 6.0.1
path-exists@3.0.0: {}
path-exists@4.0.0: {}
@@ -9717,8 +9677,6 @@ snapshots:
es-errors: 1.3.0
is-regex: 1.2.1
safer-buffer@2.1.2: {}
sax@1.1.4: {}
sax@1.4.4: {}
@@ -10244,8 +10202,6 @@ snapshots:
undici-types@7.16.0: {}
undici@7.25.0: {}
unicode-canonical-property-names-ecmascript@2.0.1: {}
unicode-match-property-ecmascript@2.0.0:
@@ -10326,12 +10282,6 @@ snapshots:
dependencies:
sdp: 3.2.1
whatwg-encoding@3.1.1:
dependencies:
iconv-lite: 0.6.3
whatwg-mimetype@4.0.0: {}
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
+2
View File
@@ -0,0 +1,2 @@
[toolchain]
channel = "1.92.0"
-288
View File
@@ -1,288 +0,0 @@
import path from "node:path"
import {promises as fs} from "node:fs"
import {fileURLToPath} from "node:url"
import "dotenv/config"
import {serve} from "@hono/node-server"
import {serveStatic} from "@hono/node-server/serve-static"
import {loadRelay} from "@welshman/app"
import {displayRelayUrl, normalizeRelayUrl} from "@welshman/util"
import {load} from "cheerio"
import {Hono} from "hono"
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const BUILD_DIR = path.join(__dirname, "build")
const INDEX_PATH = path.join(BUILD_DIR, "index.html")
const PORT = parseInt(process.env.PORT || "", 10) || 3000
const HOST = process.env.HOST || "0.0.0.0"
let TEMPLATE_HTML = ""
try {
TEMPLATE_HTML = await fs.readFile(INDEX_PATH, "utf8")
} catch (error) {
console.error(`Unable to read ${INDEX_PATH}. Run "pnpm run build" first.`)
process.exit(1)
}
const PLATFORM_NAME = process.env.VITE_PLATFORM_NAME
const PLATFORM_DESCRIPTION = process.env.VITE_PLATFORM_DESCRIPTION
// Match client-side decode logic
const decodeRelay = url => {
try {
return normalizeRelayUrl(decodeURIComponent(url))
} catch {
return undefined
}
}
const requestUrlFromContext = context => {
const requestUrl = new URL(context.req.url)
const forwardedProto = context.req.header("x-forwarded-proto")?.split(",")[0]?.trim()
const forwardedHost = context.req.header("x-forwarded-host")?.split(",")[0]?.trim()
if (forwardedProto === "http" || forwardedProto === "https") {
requestUrl.protocol = `${forwardedProto}:`
}
if (forwardedHost) {
requestUrl.host = forwardedHost
}
return requestUrl
}
const fetchRelayMeta = async relayUrl => {
if (!relayUrl) return undefined
try {
return await loadRelay(normalizeRelayUrl(relayUrl))
} catch (err) {
console.error(`Failed to fetch relay metadata for ${relayUrl}:`, err)
return undefined
}
}
const buildDefaultImage = requestUrl => {
return new URL("/maskable-icon-512x512.png", requestUrl.origin).toString()
}
const getMetadataForInvite = async (url, match) => {
const relayParam = url.searchParams.get("r")
if (!relayParam) return undefined
const relayMetadata = await fetchRelayMeta(relayParam)
if (!relayMetadata) return undefined
const relayDisplay = displayRelayUrl(relayParam)
const spaceName = relayMetadata.name
const relayDescription = relayMetadata.description
const title = spaceName
? `Invite to ${spaceName} on ${PLATFORM_NAME}`
: `Invite to a Space on ${PLATFORM_NAME}`
const parts = []
if (spaceName) {
parts.push(`You are invited to join ${spaceName} on ${PLATFORM_NAME}.`)
} else {
parts.push(`You are invited to join a space on ${PLATFORM_NAME}.`)
}
if (relayDisplay) parts.push(`Relay: ${relayDisplay}.`)
if (relayDescription) parts.push(relayDescription)
else parts.push(PLATFORM_DESCRIPTION)
const description = parts.join(" ")
const image =
relayMetadata.icon ||
relayMetadata.picture ||
relayMetadata.image ||
buildDefaultImage(url)
return {
title,
description,
image,
url: url.toString(),
site: url.origin,
}
}
const getMetadataForSpace = async (url, match) => {
const relayParam = decodeRelay(match[1])
if (!relayParam) return undefined
const relayMetadata = await fetchRelayMeta(relayParam)
if (!relayMetadata) return undefined
const spaceName = relayMetadata.name || displayRelayUrl(relayParam)
return {
title: `${spaceName} on ${PLATFORM_NAME}`,
description: relayMetadata.description || PLATFORM_DESCRIPTION,
image:
relayMetadata.icon ||
relayMetadata.picture ||
relayMetadata.image ||
buildDefaultImage(url),
url: url.toString(),
site: url.origin,
}
}
const getMetadataForSpaceSection = async (url, match) => {
const spaceMeta = await getMetadataForSpace(url, match)
if (!spaceMeta) return undefined
const section = match[2]
const sectionName = section.charAt(0).toUpperCase() + section.slice(1)
spaceMeta.title = `${sectionName} on ${spaceMeta.title}`
return spaceMeta
}
const getMetadataForSpaceItem = async (url, match) => {
const spaceMeta = await getMetadataForSpace(url, match)
if (!spaceMeta) return undefined
const section = match[2]
let itemType = "Item"
if (section === "calendar") itemType = "Event"
if (section === "threads") itemType = "Thread"
if (section === "polls") itemType = "Poll"
if (section === "goals") itemType = "Goal"
if (section === "classifieds") itemType = "Listing"
spaceMeta.title = `${itemType} on ${spaceMeta.title}`
return spaceMeta
}
const getMetadataForRoom = async (url, match) => {
const spaceMeta = await getMetadataForSpace(url, match)
if (!spaceMeta) return undefined
// Room metadata requires fetching from Nostr, which can be added later.
spaceMeta.title = `Room on ${spaceMeta.title}`
return spaceMeta
}
const routes = [
[/^\/join\/?$/, getMetadataForInvite],
[/^\/spaces\/([^/]+)\/(calendar|chat|threads|polls|goals|classifieds|recent)\/?$/, getMetadataForSpaceSection],
[/^\/spaces\/([^/]+)\/(calendar|threads|polls|goals|classifieds)\/([^/]+)\/?$/, getMetadataForSpaceItem],
[/^\/spaces\/([^/]+)\/([^/]+)\/?$/, getMetadataForRoom],
[/^\/spaces\/([^/]+)\/?$/, getMetadataForSpace],
]
const getMetadataForRoute = async url => {
for (const [regex, getMetadata] of routes) {
const match = url.pathname.match(regex)
if (match) {
try {
return await getMetadata(url, match)
} catch (err) {
console.error(`Error generating metadata for route ${url.pathname}:`, err)
return undefined
}
}
}
return undefined
}
const injectMeta = metadata => {
const $ = load(TEMPLATE_HTML)
if (metadata.title) {
$("title").text(metadata.title)
$('meta[property="og:title"]').attr("content", metadata.title)
$('meta[name="twitter:title"]').attr("content", metadata.title)
}
if (metadata.description) {
$('meta[name="description"]').attr("content", metadata.description)
$('meta[property="og:description"]').attr("content", metadata.description)
$('meta[name="twitter:description"]').attr("content", metadata.description)
}
if (metadata.image) {
$('meta[property="og:image"]').attr("content", metadata.image)
$('meta[name="twitter:image"]').attr("content", metadata.image)
}
if (metadata.url) {
$('meta[property="og:url"]').attr("content", metadata.url)
$('meta[name="twitter:site"]').attr("content", metadata.site)
$('meta[name="twitter:url"]').attr("content", metadata.url)
$('link[rel="canonical"]').attr("href", metadata.url)
}
return $.html()
}
const app = new Hono()
// Only allow GET and HEAD requests
app.use("*", async (context, next) => {
const method = context.req.method
if (method !== "GET" && method !== "HEAD") {
return context.text("Method Not Allowed", 405, {Allow: "GET, HEAD"})
}
await next()
})
// Serve static assets with appropriate caching
app.use(
"*",
serveStatic({
root: BUILD_DIR,
onFound: (filePath, context) => {
const isImmutable = filePath.split(path.sep).join("/").includes("/_app/immutable/")
const cacheControl =
path.basename(filePath) === "index.html"
? "no-cache"
: isImmutable
? "public, max-age=31536000, immutable"
: "public, max-age=3600"
context.header("Cache-Control", cacheControl)
// Immutable assets are content-hashed by Vite, so the filename is itself a
// stable content identifier. Exposing it as an ETag lets clients that
// revalidate explicitly (e.g. emoji-picker-element checks its data source
// on every load) skip re-downloading large files when nothing changed.
if (isImmutable) {
context.header("ETag", `"${path.basename(filePath)}"`)
}
},
}),
)
// SPA fallback for routes that don't match static files
app.get("*", async context => {
const requestUrl = requestUrlFromContext(context)
// If the path has an extension, it's likely a missing static asset, not an SPA route
if (path.extname(requestUrl.pathname)) {
return context.text("Not found", 404)
}
const metadata = await getMetadataForRoute(requestUrl)
const html = metadata ? injectMeta(metadata) : TEMPLATE_HTML
return context.html(html, 200, {
"Cache-Control": metadata ? "no-store" : "no-cache",
})
})
serve(
{
fetch: app.fetch,
hostname: HOST,
port: PORT,
},
() => {
console.log(`Flotilla server running on http://${HOST}:${PORT}`)
},
)
+4784
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
[package]
name = "flotilla"
version = "0.1.0"
edition = "2021"
[lib]
name = "flotilla_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.5.3", features = [] }
[dependencies]
tauri = { version = "2.9.5", features = [] }
[features]
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]
+3
View File
@@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}
+7
View File
@@ -0,0 +1,7 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Default desktop capability for the main window",
"windows": ["main"],
"permissions": ["core:default"]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#fff</color>
</resources>
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

+2
View File
@@ -0,0 +1,2 @@
[toolchain]
channel = "1.92.0"
+6
View File
@@ -0,0 +1,6 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
+6
View File
@@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
flotilla_lib::run();
}
+37
View File
@@ -0,0 +1,37 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Flotilla",
"mainBinaryName": "flotilla",
"identifier": "social.flotilla.app",
"build": {
"beforeDevCommand": "pnpm dev",
"beforeBuildCommand": "pnpm build",
"devUrl": "http://localhost:1847",
"frontendDist": "../build"
},
"app": {
"security": {
"capabilities": ["default"]
},
"windows": [
{
"label": "main",
"title": "Flotilla",
"width": 1240,
"height": 775,
"resizable": true
}
]
},
"bundle": {
"active": false,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
+13 -26
View File
@@ -2,16 +2,6 @@
@config "../tailwind.config.js";
/* root */
:root {
font-family: Lato;
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
--sair: var(--safe-area-inset-right, env(safe-area-inset-right));
}
@utility pt-sai {
padding-top: var(--sait);
}
@@ -32,6 +22,16 @@
@apply pl-sai pr-sai;
}
/* root */
:root {
font-family: Lato;
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
--sair: var(--safe-area-inset-right, env(safe-area-inset-right));
}
@utility py-sai {
@apply pt-sai pb-sai;
}
@@ -235,7 +235,6 @@
:root {
font-family: Lato;
text-size-adjust: 100%;
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
@@ -328,12 +327,12 @@
.note-editor .tiptap {
--tiptap-object-bg: var(--color-base-200);
@apply input rounded-box block h-auto min-h-32 w-full p-[.65rem] pb-6;
@apply input rounded-box h-auto min-h-32 p-[.65rem] pb-6;
}
.input-editor .tiptap {
--tiptap-object-bg: var(--color-base-200);
@apply input block h-auto p-[.65rem];
@apply input h-auto p-[.65rem];
}
/* link-content, based on tiptap */
@@ -417,28 +416,16 @@ progress[value]::-webkit-progress-value {
@apply md:left-[calc(18.5rem+var(--sail))];
}
.left-content-full {
@apply md:left-[calc(3.5rem+var(--sail))];
}
/* Keyboard open state adjustments */
body.keyboard-open {
--saib: 0px;
}
body.keyboard-open .hide-on-keyboard {
display: none;
}
body.keyboard-open .chat__compose {
margin-bottom: 0;
}
/* chat view */
.chat__compose {
@apply z-compose relative mb-14 shrink-0 md:mb-0;
@apply relative z-compose mb-14 shrink-0 md:mb-0;
}
.chat__compose .chat__compose-inner {
+4 -7
View File
@@ -2,18 +2,15 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{NAME}</title>
<link rel="canonical" href="{URL}" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content" />
<meta name="theme-color" content="{ACCENT}" />
<meta name="description" content="{DESCRIPTION}" />
<meta property="og:url" content="{URL}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="{NAME}" />
<meta property="og:description" content="{DESCRIPTION}" />
<meta property="og:image" content="" />
<meta name="og:url" content="{URL}" />
<meta name="og:type" content="website" />
<meta name="og:title" content="{NAME}" />
<meta name="og:description" content="{DESCRIPTION}" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="{URL}" />
<meta name="twitter:title" content="{NAME}" />
+3 -18
View File
@@ -6,13 +6,11 @@ export type VoiceSession = {
url: string
h: string
room: LiveKitRoom
muted: boolean
cameraOn: boolean
screenShareOn: boolean
}
/** Mic mute state is separate so toggling it does not re-render video tiles. */
export const voiceMicMuted = writable(true)
export type Pubkey = string
export type VoiceParticipant = {pubkey?: Pubkey; identity: string}
@@ -29,6 +27,8 @@ export const voiceState = writable<VoiceState>(VoiceState.Disconnected)
export const currentVoiceRoom = writable<Room | undefined>(undefined)
export const participantPubkeyMap = writable<Map<string, Pubkey>>(new Map())
export const pubkeyFromLiveKitIdentity = (identity: string): string | undefined =>
/^[a-f0-9]{64}$/.test(identity.slice(0, 64)) ? identity.slice(0, 64) : undefined
@@ -41,21 +41,6 @@ export const participantKey = (p: VoiceParticipant) => p.pubkey ?? p.identity
export const speakingParticipants = writable<VoiceParticipant[]>([])
export const participantMediaState = writable(
new Map<string, {muted: boolean; cameraOn: boolean}>(),
)
export const mediaStateByIdentity = derived(
[participantMediaState, currentVoiceSession, voiceMicMuted],
([$media, $session, $micMuted]) =>
(identity: string) => {
if ($session?.room.localParticipant.identity === identity) {
return {muted: $micMuted, cameraOn: $session.cameraOn}
}
return $media.get(identity) ?? {muted: true, cameraOn: false}
},
)
export const isParticipantSpeaking = derived(
speakingParticipants,
$participants => (p: VoiceParticipant) =>
+29 -40
View File
@@ -6,16 +6,14 @@ import {
DisconnectReason,
LocalParticipant,
LocalTrackPublication,
Participant,
Room as LiveKitRoom,
RoomEvent,
Track,
TrackPublication,
supportsAudioOutputSelection,
type AudioCaptureOptions,
} from "livekit-client"
import {derived, get} from "svelte/store"
import {map, not, nthEq, reject, removeUndefined, uniqBy} from "@welshman/lib"
import {map, removeUndefined, uniqBy} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {makeHttpAuth, makeHttpAuthHeader, getTags} from "@welshman/util"
import {signer} from "@welshman/app"
@@ -24,10 +22,10 @@ import {AbortError, whenAborted, whenTimeout} from "$lib/util"
import {
currentVoiceRoom,
currentVoiceSession,
voiceMicMuted,
participantFromLiveKitIdentity,
participantKey,
participantMediaState,
participantPubkeyMap,
pubkeyFromLiveKitIdentity,
speakingParticipants,
VoiceState,
type VoiceParticipant,
@@ -77,23 +75,20 @@ export const switchVoiceActiveDevice = async (
}
}
const deleteParticipant = (identity: string) => {
participantMediaState.update(m => new Map(reject(nthEq(0, identity), [...m])))
}
const syncParticipantMedia = (participant: Participant) => {
const state = {muted: !participant.isMicrophoneEnabled, cameraOn: participant.isCameraEnabled}
participantMediaState.update(m => {
const prev = m.get(participant.identity)
if (prev?.muted === state.muted && prev?.cameraOn === state.cameraOn) return m
const addParticipant = (identity: string) => {
participantPubkeyMap.update(m => {
const next = new Map(m)
next.set(participant.identity, state)
next.set(identity, pubkeyFromLiveKitIdentity(identity) ?? "")
return next
})
}
const onParticipantMediaChanged = (_publication: TrackPublication, participant: Participant) => {
syncParticipantMedia(participant)
const deleteParticipant = (identity: string) => {
participantPubkeyMap.update(m => {
const next = new Map(m)
next.delete(identity)
return next
})
}
const fetchLivekitToken = async (
@@ -129,15 +124,15 @@ export const deriveVoiceParticipants = (url: string, h: string) =>
// We use the livekit identity list while in a call, and fall back to the list in kind 39004.
derived(
[
participantMediaState,
participantPubkeyMap,
currentVoiceRoom,
deriveLatestEventForUrl(url, [{kinds: [LIVEKIT_PARTICIPANTS], "#d": [h]}]),
],
([$participantMediaState, $currentVoiceRoom, $publishedParticipantList]) => {
const inCall = $participantMediaState.size > 0 && $currentVoiceRoom?.id === makeRoomId(url, h)
([$participantPubkeyMap, $currentVoiceRoom, $publishedParticipantList]) => {
const inCall = $participantPubkeyMap.size > 0 && $currentVoiceRoom?.id === makeRoomId(url, h)
if (inCall) {
const participants = [...$participantMediaState.keys()].map(participantFromLiveKitIdentity)
const participants = [...$participantPubkeyMap.keys()].map(participantFromLiveKitIdentity)
return uniqBy((p: VoiceParticipant) => participantKey(p), participants)
} else {
const latestEvent = $publishedParticipantList as TrustedEvent | undefined
@@ -178,7 +173,6 @@ const setUpMicrophone = async (
const onRoomDisconnected = (reason?: DisconnectReason) => {
videoPrimaryTileKey.set(undefined)
voiceMicMuted.set(true)
currentVoiceSession.set(undefined)
resetVideoCallLayout()
if (reason !== undefined && reason !== DisconnectReason.CLIENT_INITIATED) {
@@ -190,7 +184,7 @@ const onRoomDisconnected = (reason?: DisconnectReason) => {
pushToast({theme: "error", message})
}
speakingParticipants.set([])
participantMediaState.set(new Map())
participantPubkeyMap.set(new Map())
}
const onTrackSubscribed = (track: Track) => {
@@ -220,8 +214,8 @@ const playJoinSound = () => {
audio.play().catch(() => {})
}
const onParticipantConnected = (participant: Participant) => {
syncParticipantMedia(participant)
const onParticipantConnected = (participant: {identity: string}) => {
addParticipant(participant.identity)
playJoinSound()
}
@@ -279,16 +273,11 @@ export const joinVoiceRoom = async (
liveKitRoom.on(RoomEvent.TrackUnsubscribed, onTrackUnsubscribed)
liveKitRoom.on(RoomEvent.LocalTrackUnpublished, onLocalTrackUnpublished)
liveKitRoom.on(RoomEvent.ActiveSpeakersChanged, onActiveSpeakersChanged)
liveKitRoom.on(RoomEvent.TrackMuted, onParticipantMediaChanged)
liveKitRoom.on(RoomEvent.TrackUnmuted, onParticipantMediaChanged)
liveKitRoom.on(RoomEvent.TrackPublished, onParticipantMediaChanged)
liveKitRoom.on(RoomEvent.TrackUnpublished, onParticipantMediaChanged)
liveKitRoom.on(RoomEvent.LocalTrackPublished, onParticipantMediaChanged)
try {
await Promise.race([
liveKitRoom.connect(server_url, participant_token, {maxRetries: 0}),
whenTimeout(15_000, {
whenTimeout(5_000, {
message: "Connection timed out. Please check your network and try again.",
}),
whenAborted(signal),
@@ -298,19 +287,19 @@ export const joinVoiceRoom = async (
throw e
}
participantMediaState.set(new Map())
syncParticipantMedia(liveKitRoom.localParticipant)
participantPubkeyMap.set(new Map())
addParticipant(liveKitRoom.localParticipant.identity)
for (const p of liveKitRoom.remoteParticipants.values()) {
syncParticipantMedia(p)
addParticipant(p.identity)
}
const muted = await setUpMicrophone(startMuted, preferredMicId, liveKitRoom.localParticipant)
voiceMicMuted.set(muted)
currentVoiceSession.set({
url,
h,
room: liveKitRoom,
muted,
cameraOn: false,
screenShareOn: false,
})
@@ -350,12 +339,11 @@ export const leaveVoiceRoom = async () => {
voiceState.set(VoiceState.Disconnected)
videoPrimaryTileKey.set(undefined)
voiceMicMuted.set(true)
currentVoiceSession.set(undefined)
resetVideoCallLayout()
session.room.disconnect()
speakingParticipants.set([])
participantMediaState.set(new Map())
participantPubkeyMap.set(new Map())
}
export const rejoinVoiceRoom = async (): Promise<void> => {
@@ -368,17 +356,18 @@ export const toggleMute = async () => {
const session = get(currentVoiceSession)
if (!session) return
voiceMicMuted.update(not)
if (get(voiceMicMuted)) {
const muted = !session.muted
if (muted) {
// Disable and re-enable microphone to trigger permission prompt
session.room.localParticipant.setMicrophoneEnabled(false)
currentVoiceSession.set({...session, muted})
return
}
try {
await session.room.localParticipant.setMicrophoneEnabled(true)
currentVoiceSession.set({...session, muted})
} catch (e) {
voiceMicMuted.set(true)
pushToast({theme: "error", message: "Could not access microphone"})
}
}
@@ -19,17 +19,15 @@
const end = $derived(parseInt(meta.end))
</script>
<div class="flex flex-col justify-between gap-1">
<p class="text-lg">{meta.title || meta.name}</p>
<div class="flex grow flex-wrap justify-between gap-2">
<p class="text-xl">{meta.title || meta.name}</p>
{#if !isNaN(start) && !isNaN(end)}
{@const startDateDisplay = formatTimestampAsDate(start)}
{@const endDateDisplay = formatTimestampAsDate(end)}
{@const isSingleDay = startDateDisplay === endDateDisplay}
<div class="flex flex-wrap gap-2 text-xs">
<div class="flex items-center gap-2">
<Icon icon={ClockCircle} size={4} />
{formatTimestampAsDate(start)}
</div>
<div class="flex items-center gap-2 text-sm">
<Icon icon={ClockCircle} size={4} />
<span class="hidden sm:block">{formatTimestampAsDate(start)}</span>
{formatTimestampAsTime(start)}{isSingleDay
? formatTimestampAsTime(end)
: formatTimestamp(end)}
+4 -5
View File
@@ -53,7 +53,7 @@
import ChatComposeEdit from "@app/components/ChatComposeEdit.svelte"
import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
import ThunkToast from "@app/components/ThunkToast.svelte"
import {userSettingsValues, deriveChat, makeChatId} from "@app/core/state"
import {userSettingsValues, deriveChat} from "@app/core/state"
import {pushModal} from "@app/util/modal"
import {DraftKey} from "@app/util/drafts"
import {makeDelete, prependParent} from "@app/core/commands"
@@ -66,9 +66,8 @@
const {pubkeys, info}: Props = $props()
const chatId = makeChatId(pubkeys)
const chat = deriveChat(chatId)
const draftKey = new DraftKey<{content?: string | object}>(`dm:${chatId}`)
const chat = deriveChat(pubkeys)
const draftKey = new DraftKey<{content?: string | object}>(`dm:${$chat?.id}`)
const others = remove($pubkey!, pubkeys)
const missingRelayLists = $derived(others.filter(pk => !$messagingRelayListsByPubkey.has(pk)))
@@ -280,7 +279,7 @@
</div>
</PageBar>
<PageContent class="flex flex-col-reverse gap-2 py-4">
<PageContent class="flex flex-col-reverse gap-2 pt-4">
{#if missingRelayLists.length > 0}
<div class="py-12">
<div class="card2 col-2 m-auto max-w-md items-center text-center">
-4
View File
@@ -6,7 +6,6 @@
truncate,
renderAsHtml,
isText,
isEmail,
isEmoji,
isTopic,
isCode,
@@ -27,7 +26,6 @@
import Button from "@lib/components/Button.svelte"
import ContentToken from "@app/components/ContentToken.svelte"
import ContentEmoji from "@app/components/ContentEmoji.svelte"
import ContentEmail from "@app/components/ContentEmail.svelte"
import ContentCode from "@app/components/ContentCode.svelte"
import ContentLinkInline from "@app/components/ContentLinkInline.svelte"
import ContentLinkBlock from "@app/components/ContentLinkBlock.svelte"
@@ -161,8 +159,6 @@
<ContentTopic value={parsed.value} />
{:else if isEmoji(parsed)}
<ContentEmoji value={parsed.value} />
{:else if isEmail(parsed)}
<ContentEmail value={parsed.value} />
{:else if isCode(parsed)}
<ContentCode
value={parsed.value}
-12
View File
@@ -1,12 +0,0 @@
<script lang="ts">
import LinkRound from "@assets/icons/link-round.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
export let value: string
</script>
<Link external href="mailto:{value}">
<Icon icon={LinkRound} size={3} />
{value}
</Link>
+46 -54
View File
@@ -5,32 +5,30 @@
import {preventDefault, stopPropagation} from "@lib/html"
import Link from "@lib/components/Link.svelte"
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte"
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
import {pushModal} from "@app/util/modal"
import {
dufflepud,
IMAGE_CONTENT_TYPES,
PLATFORM_URL,
IMAGE_CONTENT_TYPES,
VIDEO_CONTENT_TYPES,
THUMBNAIL_URL,
isRoomId,
} from "@app/core/state"
import {makeSpacePath} from "@app/util/routes"
const {value, event} = $props()
let hideImage = $state(false)
const url = value.url.toString()
const isRoomOrRelay = isRoomId(url) || isRelayUrl(url)
const fileType = getTagValue("file-type", event.tags) || ""
const [href, external] = call(() => {
if (isRelayUrl(url)) return [makeSpacePath(url), false]
if (url.startsWith(PLATFORM_URL)) return [url.replace(PLATFORM_URL, ""), false]
return [url, true]
})
const fileType = getTagValue("file-type", event.tags) || ""
const getVideoPoster = (videoUrl: string): string | undefined => {
if (Capacitor.getPlatform() === "android" && THUMBNAIL_URL) {
return `${THUMBNAIL_URL}/thumbnail?url=${encodeURIComponent(videoUrl)}`
@@ -56,52 +54,46 @@
const expand = () => pushModal(ContentLinkDetail, {value, event}, {fullscreen: true})
</script>
{#if isRoomOrRelay}
<div>
<ContentLinkUrl {url} class="link-content whitespace-nowrap" />
<Link {external} {href} class="my-2 block">
<div class="overflow-hidden rounded-box">
{#if url.match(/\.(mov|webm|mp4)$/) || VIDEO_CONTENT_TYPES.includes(fileType)}
<video
controls
src={url}
poster={getVideoPoster(url)}
preload="metadata"
class="max-h-96 rounded-box object-contain object-center">
<track kind="captions" />
</video>
{:else if url.match(/\.(jpe?g|png|gif|webp)$/) || IMAGE_CONTENT_TYPES.includes(fileType)}
<button type="button" onclick={stopPropagation(preventDefault(expand))}>
<ContentLinkBlockImage {value} {event} class="m-auto max-h-96 rounded-box" />
</button>
{:else}
{#await loadPreview()}
<div class="center my-12 w-full">
<span class="loading loading-spinner"></span>
</div>
{:then preview}
<div class="bg-alt flex max-w-xl flex-col leading-normal">
{#if preview.image && !hideImage}
<img
alt=""
onerror={onError}
src={preview.image}
class="bg-alt max-h-72 rounded-t-box object-contain object-center" />
{/if}
<div class="flex flex-col gap-2 p-4">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap"
>{preview.title || displayUrl(url)}</strong>
<p>{ellipsize(preview.description, 140)}</p>
</div>
</div>
{:catch}
<p class="bg-alt p-12 text-center leading-normal">
Unable to load a preview for {url}
</p>
{/await}
{/if}
</div>
{:else}
<Link {external} {href} class="my-2 block">
<div class="overflow-hidden rounded-box">
{#if url.match(/\.(mov|webm|mp4)$/) || VIDEO_CONTENT_TYPES.includes(fileType)}
<video
controls
src={url}
poster={getVideoPoster(url)}
preload="metadata"
class="max-h-96 rounded-box object-contain object-center">
<track kind="captions" />
</video>
{:else if url.match(/\.(jpe?g|png|gif|webp)$/) || IMAGE_CONTENT_TYPES.includes(fileType)}
<button type="button" onclick={stopPropagation(preventDefault(expand))}>
<ContentLinkBlockImage {value} {event} class="m-auto max-h-96 rounded-box" />
</button>
{:else}
{#await loadPreview()}
<div class="center my-12 w-full">
<span class="loading loading-spinner"></span>
</div>
{:then preview}
<div class="bg-alt flex max-w-xl flex-col leading-normal">
{#if preview.image && !hideImage}
<img
alt=""
onerror={onError}
src={preview.image}
class="bg-alt max-h-72 rounded-t-box object-contain object-center" />
{/if}
<div class="flex flex-col gap-2 p-4">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap"
>{preview.title || displayUrl(url)}</strong>
<p>{ellipsize(preview.description, 140)}</p>
</div>
</div>
{:catch}
<p class="bg-alt p-12 text-center leading-normal">
Unable to load a preview for {url}
</p>
{/await}
{/if}
</div>
</Link>
{/if}
</Link>
+15 -5
View File
@@ -1,18 +1,25 @@
<script lang="ts">
import {displayUrl} from "@welshman/lib"
import {getTagValue} from "@welshman/util"
import {call, displayUrl} from "@welshman/lib"
import {isRelayUrl, getTagValue} from "@welshman/util"
import {preventDefault, stopPropagation} from "@lib/html"
import LinkRound from "@assets/icons/link-round.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte"
import {pushModal} from "@app/util/modal"
import {IMAGE_CONTENT_TYPES} from "@app/core/state"
import {PLATFORM_URL, IMAGE_CONTENT_TYPES} from "@app/core/state"
import {makeSpacePath} from "@app/util/routes"
const {value, event} = $props()
const url = value.url.toString()
const fileType = getTagValue("file-type", event.tags) || ""
const [href, external] = call(() => {
if (isRelayUrl(url)) return [makeSpacePath(url), false]
if (url.startsWith(PLATFORM_URL)) return [url.replace(PLATFORM_URL, ""), false]
return [url, true]
})
const expand = () => pushModal(ContentLinkDetail, {value, event}, {fullscreen: true})
</script>
@@ -27,5 +34,8 @@
{displayUrl(url)}
</a>
{:else}
<ContentLinkUrl {url} class="link-content whitespace-nowrap" />
<Link {external} {href} class="link-content whitespace-nowrap">
<Icon icon={LinkRound} size={3} class="inline-block" />
{displayUrl(url)}
</Link>
{/if}
-59
View File
@@ -1,59 +0,0 @@
<script lang="ts">
import {call, displayUrl} from "@welshman/lib"
import {displayRelayUrl, isRelayUrl, normalizeRelayUrl} from "@welshman/util"
import LinkRound from "@assets/icons/link-round.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
import {PLATFORM_URL, displayRoom, isRoomId, splitRoomId} from "@app/core/state"
import {makeRoomPath, makeSpacePath} from "@app/util/routes"
const {
url,
class: className = "",
}: {
url: string
class?: string
} = $props()
const roomReference = call(() => {
if (!isRoomId(url)) {
return undefined
}
const [roomUrl, h] = splitRoomId(url)
if (!roomUrl || !h || !isRelayUrl(roomUrl)) {
return undefined
}
return {url: normalizeRelayUrl(roomUrl), h}
})
const relayReference = call(() => {
if (roomReference || !isRelayUrl(url)) {
return undefined
}
return normalizeRelayUrl(url)
})
const [href, external] = call(() => {
if (roomReference) return [makeRoomPath(roomReference.url, roomReference.h), false]
if (relayReference) return [makeSpacePath(relayReference), false]
if (url.startsWith(PLATFORM_URL)) return [url.replace(PLATFORM_URL, ""), false]
return [url, true]
})
</script>
<Link {external} {href} class={className}>
{#if roomReference}
~<span class="text-primary">{displayRelayUrl(roomReference.url)}</span> /
{displayRoom(roomReference.url, roomReference.h)}
{:else if relayReference}
<span class="text-primary">{displayRelayUrl(relayReference)}</span>
{:else}
<Icon icon={LinkRound} size={3} class="inline-block" />
{displayUrl(url)}
{/if}
</Link>
-4
View File
@@ -7,7 +7,6 @@
renderAsHtml,
isText,
isEmoji,
isEmail,
isTopic,
isCode,
isCashu,
@@ -25,7 +24,6 @@
import Button from "@lib/components/Button.svelte"
import ContentToken from "@app/components/ContentToken.svelte"
import ContentEmoji from "@app/components/ContentEmoji.svelte"
import ContentEmail from "@app/components/ContentEmail.svelte"
import ContentCode from "@app/components/ContentCode.svelte"
import ContentLinkInline from "@app/components/ContentLinkInline.svelte"
import ContentNewline from "@app/components/ContentNewline.svelte"
@@ -111,8 +109,6 @@
<ContentTopic value={parsed.value} />
{:else if isEmoji(parsed)}
<ContentEmoji value={parsed.value} />
{:else if isEmail(parsed)}
<ContentEmail value={parsed.value} />
{:else if isCode(parsed)}
<ContentCode
value={parsed.value}
+1 -1
View File
@@ -49,7 +49,7 @@
<NoteContentMinimal trimParent {url} event={$quote} />
</div>
{:else}
<NoteCard noShadow event={$quote} {url} class="bg-alt rounded-box p-4">
<NoteCard event={$quote} {url} class="bg-alt rounded-box p-4">
<NoteContentMinimal {url} event={$quote} />
</NoteCard>
{/if}
+2 -3
View File
@@ -42,7 +42,7 @@
let popover: Instance | undefined = $state()
</script>
<div class="join items-center rounded-full">
<Button class="join rounded-full">
{#if ENABLE_ZAPS && !hideZap}
<ZapButton {url} {event} class="btn join-item btn-neutral btn-xs">
<Icon icon={Bolt} size={4} />
@@ -52,7 +52,6 @@
<Icon icon={SmileCircle} size={4} />
</EmojiButton>
<Tippy
class="flex"
bind:popover
component={EventMenu}
props={{url, noun, event, customActions, onClick: hidePopover}}
@@ -61,4 +60,4 @@
<Icon icon={MenuDots} size={4} />
</Button>
</Tippy>
</div>
</Button>
+2 -2
View File
@@ -68,7 +68,7 @@
})
const observer = new ResizeObserver(() => {
spacer!.style.minHeight = `${form!.offsetHeight + 60}px`
spacer!.style.minHeight = `${form!.offsetHeight}px`
})
observer.observe(form!)
@@ -84,7 +84,7 @@
in:fly
bind:this={form}
onsubmit={preventDefault(submit)}
class="left-content bottom-sai right-sai fixed z-feature mb-14 md:mb-0 w-full md:w-auto pr-2">
class="left-content bottom-sai right-sai ml-2 pl-2 fixed z-feature">
<div class="card2 mx-2 my-2 bg-alt shadow-md">
<div class="relative">
<div class="note-editor grow overflow-hidden">
+4 -4
View File
@@ -192,16 +192,16 @@
{/snippet}
{#snippet input()}
<div class="flex grow justify-end">
<label class="input input-bordered flex w-auto items-center gap-2">
<label class="input input-bordered flex items-center gap-2">
<Icon icon={Bolt} />
<input bind:value={amount} type="number" class="w-28 grow" />
<p class="shrink-0 opacity-50">sats</p>
<input bind:value={amount} type="number" class="w-28" />
<p class="opacity-50">sats</p>
</label>
</div>
{/snippet}
</FieldInline>
<input
class="range range-primary -mt-2 w-full"
class="range range-primary -mt-2"
type="range"
min="1000"
max="100000"
+1 -7
View File
@@ -15,7 +15,6 @@
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalTitle from "@lib/components/ModalTitle.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ProgressBar from "@app/components/ProgressBar.svelte"
import {pushToast} from "@app/util/toast"
import {PLATFORM_NAME} from "@app/core/state"
@@ -23,11 +22,9 @@
secret: string
next: () => unknown
submitText?: string
step?: number
totalSteps?: number
}
const {secret, next, submitText = "Continue", step, totalSteps}: Props = $props()
const {secret, next, submitText = "Continue"}: Props = $props()
const back = () => history.back()
@@ -153,9 +150,6 @@
</Button>
</div>
</ModalBody>
{#if step && totalSteps}
<ProgressBar current={step} total={totalSteps} />
{/if}
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
-10
View File
@@ -1,5 +1,4 @@
<script lang="ts">
import {Capacitor} from "@capacitor/core"
import {onMount, onDestroy} from "svelte"
import type {Nip46ResponseWithResult} from "@welshman/signer"
import {Nip46Broker} from "@welshman/signer"
@@ -104,16 +103,10 @@
mode = "connect"
}
const openSigner = () => {
controller.launchSigner()
}
const selectBunker = () => {
mode = "bunker"
}
const isIos = Capacitor.getPlatform() === "ios"
let mode: string = $state("bunker")
$effect(() => {
@@ -145,9 +138,6 @@
<BunkerUrl {controller} />
<Button class="btn {$bunker ? 'btn-neutral' : 'btn-primary'}" onclick={selectConnect}
>Log in with a QR code instead</Button>
{#if isIos}
<Button class="btn btn-neutral" onclick={openSigner}>Open in Signer</Button>
{/if}
{/if}
</ModalBody>
<ModalFooter>
+3 -11
View File
@@ -19,7 +19,6 @@
import LogInOTP from "@app/components/LogInOTP.svelte"
import LogInSelect from "@app/components/LogInSelect.svelte"
import {deleteDeactivatedPomadeSessions, loginWithPomade} from "@app/util/pomade"
import {getPomadeLoginFailureMessage, POMADE_NETWORK_ERROR_MESSAGE} from "@app/util/pomadeErrors"
import {pushModal, clearModals} from "@app/util/modal"
import {setChecked} from "@app/util/notifications"
import {pushToast} from "@app/util/toast"
@@ -45,7 +44,7 @@
return pushToast({
theme: "error",
message: getPomadeLoginFailureMessage(messages),
message: "Sorry, we were unable to log you in.",
})
}
@@ -65,17 +64,10 @@
pushToast({
theme: "error",
message: getPomadeLoginFailureMessage(res.messages),
message: "Sorry, we were unable to log you in.",
})
}
}
} catch (error) {
console.error("Login error:", error)
pushToast({
theme: "error",
message: POMADE_NETWORK_ERROR_MESSAGE,
})
} finally {
loading = false
}
@@ -98,7 +90,7 @@
{#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2">
<Icon icon={Letter} />
<input type="email" bind:value={email} />
<input bind:value={email} />
</label>
{/snippet}
</FieldInline>
+2 -12
View File
@@ -15,7 +15,6 @@
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import LogInOTPConfirm from "@app/components/LogInOTPConfirm.svelte"
import {POMADE_NETWORK_ERROR_MESSAGE} from "@app/util/pomadeErrors"
import {pushModal} from "@app/util/modal"
import {pushToast} from "@app/util/toast"
@@ -36,20 +35,11 @@
if (ok) {
pushModal(LogInOTPConfirm, {email, peersByPrefix})
} else {
console.error("Pomade challenge request failed during OTP login")
pushToast({
theme: "error",
message: POMADE_NETWORK_ERROR_MESSAGE,
message: "Sorry, we were unable to request a login code.",
})
}
} catch (error) {
console.error(error)
pushToast({
theme: "error",
message: POMADE_NETWORK_ERROR_MESSAGE,
})
} finally {
loading = false
}
@@ -71,7 +61,7 @@
{#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2">
<Icon icon={Letter} />
<input type="email" bind:value={email} />
<input bind:value={email} />
</label>
{/snippet}
</FieldInline>
+5 -13
View File
@@ -15,11 +15,10 @@
import ModalFooter from "@lib/components/ModalFooter.svelte"
import StringMultiInput from "@lib/components/StringMultiInput.svelte"
import LogInSelect from "@app/components/LogInSelect.svelte"
import {pushModal, clearModals} from "@app/util/modal"
import {setChecked} from "@app/util/notifications"
import {deleteDeactivatedPomadeSessions, loginWithPomade} from "@app/util/pomade"
import {getPomadeLoginFailureMessage, POMADE_NETWORK_ERROR_MESSAGE} from "@app/util/pomadeErrors"
import {pushToast} from "@app/util/toast"
import {setChecked} from "@app/util/notifications"
import {pushModal, clearModals} from "@app/util/modal"
import {deleteDeactivatedPomadeSessions, loginWithPomade} from "@app/util/pomade"
type Props = {
email: string
@@ -45,7 +44,7 @@
return pushToast({
theme: "error",
message: getPomadeLoginFailureMessage(messages),
message: "Sorry, we were unable to log you in.",
})
}
@@ -65,17 +64,10 @@
pushToast({
theme: "error",
message: getPomadeLoginFailureMessage(res.messages),
message: "Sorry, we were unable to log you in.",
})
}
}
} catch (error) {
console.error("Login error:", error)
pushToast({
theme: "error",
message: POMADE_NETWORK_ERROR_MESSAGE,
})
} finally {
loading = false
}

Some files were not shown because too many files have changed in this diff Show More