Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48066a4018 | ||
|
|
5c8850ea8f | ||
|
|
09aea3cff5 | ||
|
|
45c5a890b9 |
@@ -2,7 +2,7 @@
|
||||
"name": "lume",
|
||||
"description": "the communication app",
|
||||
"private": true,
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
@@ -54,7 +54,7 @@
|
||||
"react-hook-form": "^7.46.1",
|
||||
"react-hotkeys-hook": "^4.4.1",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-player": "^2.12.0",
|
||||
"react-player": "^2.13.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-textarea-autosize": "^8.5.3",
|
||||
"react-virtuoso": "^4.5.0",
|
||||
@@ -67,7 +67,7 @@
|
||||
"zustand": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@tauri-apps/cli": "^1.4.0",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
||||
"@types/html-to-text": "^9.0.1",
|
||||
|
||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@@ -110,8 +110,8 @@ dependencies:
|
||||
specifier: ^8.0.7
|
||||
version: 8.0.7(@types/react@18.2.21)(react@18.2.0)
|
||||
react-player:
|
||||
specifier: ^2.12.0
|
||||
version: 2.12.0(react@18.2.0)
|
||||
specifier: ^2.13.0
|
||||
version: 2.13.0(react@18.2.0)
|
||||
react-router-dom:
|
||||
specifier: ^6.15.0
|
||||
version: 6.15.0(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -145,8 +145,8 @@ dependencies:
|
||||
|
||||
devDependencies:
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.9
|
||||
version: 0.5.9(tailwindcss@3.3.3)
|
||||
specifier: ^0.5.10
|
||||
version: 0.5.10(tailwindcss@3.3.3)
|
||||
'@tauri-apps/cli':
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
@@ -1695,15 +1695,15 @@ packages:
|
||||
resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==}
|
||||
dependencies:
|
||||
'@noble/curves': 1.1.0
|
||||
'@noble/hashes': 1.3.2
|
||||
'@scure/base': 1.1.3
|
||||
'@noble/hashes': 1.3.1
|
||||
'@scure/base': 1.1.1
|
||||
dev: false
|
||||
|
||||
/@scure/bip39@1.2.1:
|
||||
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
|
||||
dependencies:
|
||||
'@noble/hashes': 1.3.2
|
||||
'@scure/base': 1.1.3
|
||||
'@noble/hashes': 1.3.1
|
||||
'@scure/base': 1.1.1
|
||||
dev: false
|
||||
|
||||
/@selderee/plugin-htmlparser2@0.11.0:
|
||||
@@ -1835,8 +1835,8 @@ packages:
|
||||
resolution: {integrity: sha512-z/G02d+59gyyUb7KYhKi9jOhicek6QD2oMaotUyG+lUkybpXoV49dY9bj7Ah5Q+y7knK2jU67UTX9FyfGzaxQg==}
|
||||
dev: true
|
||||
|
||||
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.3):
|
||||
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
|
||||
/@tailwindcss/typography@0.5.10(tailwindcss@3.3.3):
|
||||
resolution: {integrity: sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==}
|
||||
peerDependencies:
|
||||
tailwindcss: '>=3.0.0 || insiders'
|
||||
dependencies:
|
||||
@@ -2872,7 +2872,7 @@ packages:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.21.10
|
||||
caniuse-lite: 1.0.30001525
|
||||
caniuse-lite: 1.0.30001527
|
||||
fraction.js: 4.3.6
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.0
|
||||
@@ -2924,7 +2924,7 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001525
|
||||
caniuse-lite: 1.0.30001527
|
||||
electron-to-chromium: 1.4.508
|
||||
node-releases: 2.0.13
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.10)
|
||||
@@ -2959,8 +2959,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/caniuse-lite@1.0.30001525:
|
||||
resolution: {integrity: sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==}
|
||||
/caniuse-lite@1.0.30001527:
|
||||
resolution: {integrity: sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==}
|
||||
dev: true
|
||||
|
||||
/case-anything@2.1.13:
|
||||
@@ -3354,7 +3354,7 @@ packages:
|
||||
safe-regex-test: 1.0.0
|
||||
string.prototype.trim: 1.2.7
|
||||
string.prototype.trimend: 1.0.6
|
||||
string.prototype.trimstart: 1.0.6
|
||||
string.prototype.trimstart: 1.0.7
|
||||
typed-array-buffer: 1.0.0
|
||||
typed-array-byte-length: 1.0.0
|
||||
typed-array-byte-offset: 1.0.0
|
||||
@@ -5255,7 +5255,7 @@ packages:
|
||||
pidtree: 0.3.1
|
||||
read-pkg: 3.0.0
|
||||
shell-quote: 1.8.1
|
||||
string.prototype.padend: 3.1.4
|
||||
string.prototype.padend: 3.1.5
|
||||
dev: false
|
||||
|
||||
/npm-run-path@5.1.0:
|
||||
@@ -5917,8 +5917,8 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/react-player@2.12.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-rymLRz/2GJJD+Wc01S7S+i9pGMFYnNmQibR2gVE3KmHJCBNN8BhPAlOPTGZtn1uKpJ6p4RPLlzPQ1OLreXd8gw==}
|
||||
/react-player@2.13.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-gkY7ZdbVFztlKFFhCPcnDrFQm+L399b8fhWsKatZ+b2wpKJwfUHBXQFMRxqYQGT0ic1/wQ7D7EZEWy7ZBqk2pw==}
|
||||
peerDependencies:
|
||||
react: '>=16.6.0'
|
||||
dependencies:
|
||||
@@ -6379,8 +6379,8 @@ packages:
|
||||
side-channel: 1.0.4
|
||||
dev: true
|
||||
|
||||
/string.prototype.padend@3.1.4:
|
||||
resolution: {integrity: sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==}
|
||||
/string.prototype.padend@3.1.5:
|
||||
resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
@@ -6403,8 +6403,8 @@ packages:
|
||||
define-properties: 1.2.0
|
||||
es-abstract: 1.22.1
|
||||
|
||||
/string.prototype.trimstart@1.0.6:
|
||||
resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
|
||||
/string.prototype.trimstart@1.0.7:
|
||||
resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.2.0
|
||||
|
||||
24
src-tauri/Cargo.lock
generated
24
src-tauri/Cargo.lock
generated
@@ -533,9 +533,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.13.1"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
|
||||
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -695,9 +695,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.28"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f"
|
||||
checksum = "d87d9d13be47a5b7c3907137f1290b0459a7f80efb26be8c52afb11963bccb02"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
@@ -2642,7 +2642,6 @@ dependencies = [
|
||||
"tauri-plugin-stronghold",
|
||||
"tauri-plugin-upload",
|
||||
"webpage",
|
||||
"window-shadows",
|
||||
"window-vibrancy",
|
||||
]
|
||||
|
||||
@@ -5709,9 +5708,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.3"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
|
||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
@@ -5971,17 +5970,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "window-shadows"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/tauri-apps/window-shadows?branch=dev#a9f5f1f7725609c71404539befca1f1a98095cd2"
|
||||
dependencies = [
|
||||
"cocoa 0.25.0",
|
||||
"objc",
|
||||
"raw-window-handle",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "window-vibrancy"
|
||||
version = "0.4.0"
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
[package]
|
||||
name = "lume"
|
||||
version = "1.2.2"
|
||||
version = "1.2.3"
|
||||
description = "the communication app"
|
||||
authors = ["Ren Amamiya"]
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/luminous-devs/lume"
|
||||
edition = "2021"
|
||||
rust-version = "1.71"
|
||||
rust-version = "1.66"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.4.0", features = [] }
|
||||
tauri-build = { version = "1.4", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.4.0", features = [
|
||||
tauri = { version = "1.4", features = [
|
||||
"fs-read-dir",
|
||||
"fs-read-file",
|
||||
"window-start-dragging",
|
||||
@@ -46,7 +46,6 @@ tauri-plugin-stronghold = { git = "https://github.com/tauri-apps/plugins-workspa
|
||||
tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
tauri-plugin-upload = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
window-vibrancy = { git = "https://github.com/tauri-apps/window-vibrancy", branch = "dev" }
|
||||
window-shadows = { git = "https://github.com/tauri-apps/window-shadows", branch = "dev" }
|
||||
sqlx-cli = { version = "0.7.0", default-features = false, features = [
|
||||
"sqlite",
|
||||
] }
|
||||
@@ -54,8 +53,11 @@ rust-argon2 = "1.0"
|
||||
webpage = { version = "1.6.0", features = ["serde"] }
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
# DO NOT REMOVE!!
|
||||
# by default Tauri runs in production mode
|
||||
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
|
||||
default = ["custom-protocol"]
|
||||
# this feature is used used for production builds where `devPath` points to the filesystem
|
||||
# DO NOT remove this
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
# Optimized for bundle size. If you want faster builds comment out/delete this section.
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_autostart::MacosLauncher;
|
||||
use tauri_plugin_sql::{Migration, MigrationKind};
|
||||
use window_shadows::set_shadow;
|
||||
use webpage::{Webpage, WebpageOptions};
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -103,9 +102,6 @@ fn main() {
|
||||
apply_vibrancy(&window, NSVisualEffectMaterial::HudWindow, None, None)
|
||||
.expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS");
|
||||
|
||||
// set native shadow
|
||||
set_shadow(&window, true).expect("Unsupported platform!");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.plugin(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"build": {
|
||||
"beforeBuildCommand": "pnpm build",
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
@@ -8,7 +9,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "Lume",
|
||||
"version": "1.2.2"
|
||||
"version": "1.2.3"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"tauri": {
|
||||
"windows": [
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"tauri": {
|
||||
"macOSPrivateApi": true,
|
||||
"windows": [
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"tauri": {
|
||||
"windows": [
|
||||
{
|
||||
|
||||
@@ -118,10 +118,11 @@ export function OnboardStep3Screen() {
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
|
||||
</div>
|
||||
) : relaysAsArray.length === 0 ? (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<div className="flex h-full w-full items-center justify-center px-6">
|
||||
<p className="text-center text-white/50">
|
||||
Can't found any relays, you can skip this step and use default relays
|
||||
instead
|
||||
Lume couldn't find any relays from your follows.
|
||||
<br />
|
||||
You can skip this step and use default relays instead.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
@@ -145,7 +146,7 @@ export function OnboardStep3Screen() {
|
||||
))
|
||||
)}
|
||||
{relays.size > 5 && (
|
||||
<div className="sticky bottom-0 left-0 inline-flex w-full items-center justify-center bg-white/10 px-4 py-2 backdrop-blur-2xl backdrop-blur-xl">
|
||||
<div className="sticky bottom-0 left-0 inline-flex w-full items-center justify-center bg-white/10 px-4 py-2 backdrop-blur-2xl">
|
||||
<p className="text-sm text-orange-400">
|
||||
Using too much relay can cause high resource usage
|
||||
</p>
|
||||
|
||||
@@ -2,9 +2,17 @@ import { useCallback } from 'react';
|
||||
|
||||
import { useStorage } from '@libs/storage/provider';
|
||||
|
||||
import {
|
||||
ArticleIcon,
|
||||
FileIcon,
|
||||
FollowsIcon,
|
||||
GroupFeedsIcon,
|
||||
HashtagIcon,
|
||||
TrendingIcon,
|
||||
} from '@shared/icons';
|
||||
import { TitleBar } from '@shared/titleBar';
|
||||
|
||||
import { DefaultWidgets, useWidgets } from '@stores/widgets';
|
||||
import { DefaultWidgets, WidgetKinds, useWidgets } from '@stores/widgets';
|
||||
|
||||
import { Widget, WidgetGroup, WidgetGroupItem } from '@utils/types';
|
||||
|
||||
@@ -20,16 +28,61 @@ export function WidgetList({ params }: { params: Widget }) {
|
||||
removeWidget(db, params.id);
|
||||
};
|
||||
|
||||
const renderIcon = useCallback(
|
||||
(kind: number) => {
|
||||
switch (kind) {
|
||||
case WidgetKinds.tmp.xfeed:
|
||||
return <GroupFeedsIcon className="h-5 w-5 text-white" />;
|
||||
case WidgetKinds.local.follows:
|
||||
return <FollowsIcon className="h-5 w-5 text-white" />;
|
||||
case WidgetKinds.local.files:
|
||||
case WidgetKinds.global.files:
|
||||
return <FileIcon className="h-5 w-5 text-white" />;
|
||||
case WidgetKinds.local.articles:
|
||||
case WidgetKinds.global.articles:
|
||||
return <ArticleIcon className="h-5 w-5 text-white" />;
|
||||
case WidgetKinds.tmp.xhashtag:
|
||||
return <HashtagIcon className="h-5 w-4 text-white" />;
|
||||
case WidgetKinds.nostrBand.trendingAccounts:
|
||||
case WidgetKinds.nostrBand.trendingNotes:
|
||||
return <TrendingIcon className="h-5 w-4 text-white" />;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
},
|
||||
[DefaultWidgets]
|
||||
);
|
||||
|
||||
const renderItem = useCallback(
|
||||
(row: WidgetGroup) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<h3 className="font-medium text-white/50">{row.title}</h3>
|
||||
<div className="grid grid-cols-3 gap-6">
|
||||
<div className="flex flex-col divide-y divide-white/5 overflow-hidden rounded-xl bg-white/10">
|
||||
{row.data.map((item, index) => (
|
||||
<button onClick={() => openWidget(item)} key={index}>
|
||||
<div className="inline-flex aspect-square h-full w-full transform-gpu flex-col items-center justify-center gap-2.5 rounded-2xl bg-white/5 hover:bg-white/10">
|
||||
<h5 className="text-sm font-medium">{item.title}</h5>
|
||||
<button
|
||||
onClick={() => openWidget(item)}
|
||||
key={index}
|
||||
className="flex items-center gap-2.5 px-4 hover:bg-white/10"
|
||||
>
|
||||
{item.icon ? (
|
||||
<div className="h-10 w-10 shrink-0 rounded-md">
|
||||
<img
|
||||
src={item.icon}
|
||||
alt={item.title}
|
||||
className="h-10 w-10 object-cover"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-white/10">
|
||||
{renderIcon(item.kind)}
|
||||
</div>
|
||||
)}
|
||||
<div className="inline-flex h-16 w-full flex-col items-start justify-center gap-1">
|
||||
<h5 className="line-clamp-1 font-medium leading-none">{item.title}</h5>
|
||||
<p className="line-clamp-1 text-xs leading-none text-white/50">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
@@ -41,11 +94,27 @@ export function WidgetList({ params }: { params: Widget }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="relative h-full shrink-0 grow-0 basis-[400px] overflow-hidden">
|
||||
<div className="relative h-full shrink-0 grow-0 basis-[400px] overflow-hidden bg-white/10">
|
||||
<TitleBar id={params.id} title="Add widget" />
|
||||
<div className="flex flex-col gap-8 px-3">
|
||||
<div className="flex flex-col gap-6 px-3">
|
||||
{DefaultWidgets.map((row: WidgetGroup) => renderItem(row))}
|
||||
</div>
|
||||
<div className="mt-6 px-3">
|
||||
<div className="border-t border-white/5 pt-6">
|
||||
<button
|
||||
type="button"
|
||||
disabled
|
||||
className="inline-flex h-14 w-full items-center justify-center gap-2.5 rounded-xl bg-white/5 text-sm font-medium text-white/50"
|
||||
>
|
||||
Build your own widget{' '}
|
||||
<div className="-rotate-3 transform rounded-md border border-white/20 bg-white/10 px-1.5 py-1">
|
||||
<span className="bg-gradient-to-t from-fuchsia-200 via-red-200 to-orange-300 bg-clip-text text-xs text-transparent">
|
||||
Coming soon
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,40 +17,32 @@ export const NDKInstance = () => {
|
||||
const cacheAdapter = useMemo(() => new TauriAdapter(), [ndk]);
|
||||
|
||||
// TODO: fully support NIP-11
|
||||
async function verifyRelays(relays: string[]) {
|
||||
async function getExplicitRelays() {
|
||||
try {
|
||||
const urls: string[] = relays.map((relay) => {
|
||||
if (relay.startsWith('ws')) {
|
||||
return relay.replace('ws', 'http');
|
||||
}
|
||||
if (relay.startsWith('wss')) {
|
||||
return relay.replace('wss', 'https');
|
||||
}
|
||||
});
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort('timeout'), 10000);
|
||||
|
||||
const requests = urls.map((url) =>
|
||||
fetch(url, {
|
||||
// get relays
|
||||
const relays = (await db.getExplicitRelayUrls()) ?? FULL_RELAYS;
|
||||
|
||||
const requests = relays.map((relay) => {
|
||||
const url = new URL(relay);
|
||||
|
||||
return fetch(`https://${url.hostname + url.pathname}`, {
|
||||
headers: { Accept: 'application/nostr+json' },
|
||||
signal: controller.signal,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const responses = await Promise.all(requests);
|
||||
const errors = responses.filter((response) => !response.ok);
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw errors.map((response) => Error(response.statusText));
|
||||
}
|
||||
if (errors.length > 0) throw errors.map((response) => Error(response.statusText));
|
||||
|
||||
const verifiedRelays: string[] = responses.map((res) => {
|
||||
if (res.url.startsWith('http')) {
|
||||
return res.url.replace('htto', 'ws');
|
||||
}
|
||||
if (res.url.startsWith('https')) {
|
||||
return res.url.replace('https', 'wss');
|
||||
}
|
||||
const url = new URL(res.url);
|
||||
if (url.protocol === 'http:') return `ws://${url.hostname + url.pathname}`;
|
||||
if (url.protocol === 'https:') return `wss://${url.hostname + url.pathname}`;
|
||||
});
|
||||
|
||||
// clear timeout
|
||||
@@ -59,31 +51,14 @@ export const NDKInstance = () => {
|
||||
// return all validate relays
|
||||
return verifiedRelays;
|
||||
} catch (e) {
|
||||
console.error('verify relay failed with error: ', e);
|
||||
await message(e, { title: 'Cannot connect to relays', type: 'error' });
|
||||
}
|
||||
}
|
||||
|
||||
async function initNDK() {
|
||||
let explicitRelayUrls: string[];
|
||||
const explicitRelayUrlsFromDB = await db.getExplicitRelayUrls();
|
||||
|
||||
console.log('relays in db: ', explicitRelayUrlsFromDB);
|
||||
console.log('ndk cache adapter: ', cacheAdapter);
|
||||
|
||||
if (explicitRelayUrlsFromDB) {
|
||||
explicitRelayUrls = await verifyRelays(explicitRelayUrlsFromDB);
|
||||
} else {
|
||||
explicitRelayUrls = await verifyRelays(FULL_RELAYS);
|
||||
}
|
||||
|
||||
if (explicitRelayUrls.length < 1) {
|
||||
await message('Something is wrong. No relays have been found.', {
|
||||
title: 'Lume',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
|
||||
const explicitRelayUrls = await getExplicitRelays();
|
||||
const instance = new NDK({ explicitRelayUrls, cacheAdapter });
|
||||
|
||||
try {
|
||||
await instance.connect(10000);
|
||||
} catch (error) {
|
||||
|
||||
@@ -125,7 +125,7 @@ export function Composer() {
|
||||
autoCapitalize="off"
|
||||
className={twMerge(
|
||||
'scrollbar-hide markdown max-h-[500px] overflow-y-auto break-all pr-2 outline-none',
|
||||
expand ? 'min-h-[500px]' : 'min-h-[120px]'
|
||||
expand ? 'min-h-[500px]' : reply.id ? 'min-h-min' : 'min-h-[120px]'
|
||||
)}
|
||||
/>
|
||||
{reply.id && (
|
||||
|
||||
22
src/shared/icons/article.tsx
Normal file
22
src/shared/icons/article.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { SVGProps } from 'react';
|
||||
|
||||
export function ArticleIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M16.25 12V4.75a1 1 0 00-1-1H3.75a1 1 0 00-1 1v13a2.5 2.5 0 002.5 2.5H18.5M16.25 12v5.75a2.5 2.5 0 005 0V13a1 1 0 00-1-1h-4zm-9.5 3.75h5.5m-5.5-8h5.5v4.5h-5.5v-4.5z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -13,10 +13,9 @@ export function FileIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M8.75 6.75h6.5m-6.5 4h6.5m-6.5 4h2.5m-5.5 6.5h12.5a1 1 0 001-1V3.75a1 1 0 00-1-1H5.75a1 1 0 00-1 1v16.5a1 1 0 001 1z"
|
||||
/>
|
||||
d="M12.75 3.25v5a1 1 0 001 1h5m-10 4h3.5m-3.5 4h6.5m-9.5-14.5h6.586a1 1 0 01.707.293l5.914 5.914a1 1 0 01.293.707V20.25a1 1 0 01-1 1H5.75a1 1 0 01-1-1V3.75a1 1 0 011-1z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
22
src/shared/icons/follows.tsx
Normal file
22
src/shared/icons/follows.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { SVGProps } from 'react';
|
||||
|
||||
export function FollowsIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M17.75 19.25h3.673c.581 0 1.045-.496.947-1.07-.531-3.118-2.351-5.43-5.37-5.43-.446 0-.866.05-1.26.147M11.25 7a3.25 3.25 0 11-6.5 0 3.25 3.25 0 016.5 0zm8.5.5a2.75 2.75 0 11-5.5 0 2.75 2.75 0 015.5 0zM1.87 19.18c.568-3.68 2.647-6.43 6.13-6.43 3.482 0 5.561 2.75 6.13 6.43.088.575-.375 1.07-.956 1.07H2.825c-.58 0-1.043-.495-.955-1.07z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
22
src/shared/icons/groupFeeds.tsx
Normal file
22
src/shared/icons/groupFeeds.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { SVGProps } from 'react';
|
||||
|
||||
export function GroupFeedsIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M14.425 13.18c3.361-1.396 7.598.605 8.454 6.003.09.573-.372 1.067-.952 1.067H16.75M10.75 7a3.25 3.25 0 11-6.5 0 3.25 3.25 0 016.5 0zm9 0a3.25 3.25 0 11-6.5 0 3.25 3.25 0 016.5 0zm-6.966 13.25H2.072c-.58 0-1.042-.497-.951-1.07 1.362-8.573 11.252-8.573 12.614 0 .091.573-.371 1.07-.951 1.07z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export function HashtagIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElem
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M8.75 3.75l-2 16.5m10.5-16.5l-2 16.5M3.75 7.75h16.5m0 8.5H3.75"
|
||||
/>
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,3 +58,6 @@ export * from './chevronUp';
|
||||
export * from './secure';
|
||||
export * from './verified';
|
||||
export * from './mention';
|
||||
export * from './groupFeeds';
|
||||
export * from './article';
|
||||
export * from './follows';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createJSONStorage, persist } from 'zustand/middleware';
|
||||
|
||||
import { LumeStorage } from '@libs/storage/instance';
|
||||
|
||||
import { Widget } from '@utils/types';
|
||||
import { Widget, WidgetGroup } from '@utils/types';
|
||||
|
||||
interface WidgetState {
|
||||
widgets: null | Array<Widget>;
|
||||
@@ -39,25 +39,29 @@ export const WidgetKinds = {
|
||||
},
|
||||
};
|
||||
|
||||
export const DefaultWidgets = [
|
||||
export const DefaultWidgets: Array<WidgetGroup> = [
|
||||
{
|
||||
title: 'Network / Follows',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.tmp.xfeed,
|
||||
title: 'Group feeds',
|
||||
description: 'All posts from specific people you want to keep up with',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.local.files,
|
||||
title: 'Files',
|
||||
description: 'All files shared by people in your network',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.local.articles,
|
||||
title: 'Articles',
|
||||
description: 'All articles shared by people in your network',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.local.follows,
|
||||
title: 'Follows',
|
||||
description: 'All posts from people you are following',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -67,27 +71,32 @@ export const DefaultWidgets = [
|
||||
{
|
||||
kind: WidgetKinds.tmp.xhashtag,
|
||||
title: 'Hashtag',
|
||||
description: 'All posts have a specific hashtag',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.global.files,
|
||||
title: 'Files',
|
||||
description: 'All files shared by people in your current relay set',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.global.articles,
|
||||
title: 'Articles',
|
||||
description: 'All articles shared by people in your current relay set',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Trending (nostr.band)',
|
||||
title: 'nostr.band',
|
||||
data: [
|
||||
{
|
||||
kind: WidgetKinds.nostrBand.trendingAccounts,
|
||||
title: 'Accounts',
|
||||
description: 'Trending accounts from the last 24 hours',
|
||||
},
|
||||
{
|
||||
kind: WidgetKinds.nostrBand.trendingNotes,
|
||||
title: 'Notes',
|
||||
description: 'Trending notes from the last 24 hours',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
2
src/utils/types.d.ts
vendored
2
src/utils/types.d.ts
vendored
@@ -44,7 +44,9 @@ export interface WidgetGroup {
|
||||
|
||||
export interface WidgetGroupItem {
|
||||
title: string;
|
||||
description: string;
|
||||
kind: number;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface Widget {
|
||||
|
||||
Reference in New Issue
Block a user