@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
root = true |
||||
|
||||
[*] |
||||
charset = utf-8 |
||||
indent_style = space |
||||
indent_size = 2 |
||||
end_of_line = lf |
||||
insert_final_newline = true |
||||
trim_trailing_whitespace = true |
||||
@ -1,14 +0,0 @@
@@ -1,14 +0,0 @@
|
||||
module.exports = { |
||||
extends: [ |
||||
'eslint:recommended', |
||||
'plugin:react/recommended', |
||||
'plugin:react/jsx-runtime', |
||||
'@electron-toolkit/eslint-config-ts/recommended', |
||||
'@electron-toolkit/eslint-config-prettier' |
||||
], |
||||
rules: { |
||||
'@typescript-eslint/explicit-function-return-type': 'off', |
||||
'react/prop-types': 'off', |
||||
'@typescript-eslint/no-explicit-any': 'off' |
||||
} |
||||
} |
||||
@ -1,57 +0,0 @@
@@ -1,57 +0,0 @@
|
||||
name: Build/release |
||||
|
||||
on: |
||||
push: |
||||
tags: |
||||
- v*.*.* |
||||
|
||||
permissions: |
||||
contents: write |
||||
|
||||
jobs: |
||||
release: |
||||
runs-on: ${{ matrix.os }} |
||||
|
||||
strategy: |
||||
matrix: |
||||
os: [ubuntu-latest, macos-13, windows-latest] |
||||
|
||||
steps: |
||||
- name: Check out Git repository |
||||
uses: actions/checkout@v4 |
||||
|
||||
- name: Install Node.js |
||||
uses: actions/setup-node@v4 |
||||
with: |
||||
node-version: 20 |
||||
|
||||
- name: Install Dependencies |
||||
run: npm install |
||||
|
||||
- name: build-linux |
||||
if: matrix.os == 'ubuntu-latest' |
||||
run: npm run build:linux |
||||
|
||||
- name: build-mac |
||||
if: matrix.os == 'macos-13' |
||||
run: npm run build:mac |
||||
|
||||
- name: build-win |
||||
if: matrix.os == 'windows-latest' |
||||
run: npm run build:win |
||||
|
||||
- name: release |
||||
uses: softprops/action-gh-release@v2 |
||||
with: |
||||
draft: true |
||||
files: | |
||||
dist/*.exe |
||||
dist/*.zip |
||||
dist/*.dmg |
||||
dist/*.AppImage |
||||
dist/*.snap |
||||
dist/*.deb |
||||
dist/*.rpm |
||||
dist/*.tar.gz |
||||
env: |
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} |
||||
@ -1,5 +1,24 @@
@@ -1,5 +1,24 @@
|
||||
# Logs |
||||
logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
pnpm-debug.log* |
||||
lerna-debug.log* |
||||
|
||||
node_modules |
||||
dist |
||||
out |
||||
dist-ssr |
||||
*.local |
||||
|
||||
# Editor directories and files |
||||
.vscode/* |
||||
!.vscode/extensions.json |
||||
.idea |
||||
.DS_Store |
||||
*.log* |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.sw? |
||||
|
||||
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
{ |
||||
"recommendations": ["dbaeumer.vscode-eslint"] |
||||
} |
||||
@ -1,39 +0,0 @@
@@ -1,39 +0,0 @@
|
||||
{ |
||||
"version": "0.2.0", |
||||
"configurations": [ |
||||
{ |
||||
"name": "Debug Main Process", |
||||
"type": "node", |
||||
"request": "launch", |
||||
"cwd": "${workspaceRoot}", |
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite", |
||||
"windows": { |
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd" |
||||
}, |
||||
"runtimeArgs": ["--sourcemap"], |
||||
"env": { |
||||
"REMOTE_DEBUGGING_PORT": "9222" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "Debug Renderer Process", |
||||
"port": 9222, |
||||
"request": "attach", |
||||
"type": "chrome", |
||||
"webRoot": "${workspaceFolder}/src/renderer", |
||||
"timeout": 60000, |
||||
"presentation": { |
||||
"hidden": true |
||||
} |
||||
} |
||||
], |
||||
"compounds": [ |
||||
{ |
||||
"name": "Debug All", |
||||
"configurations": ["Debug Main Process", "Debug Renderer Process"], |
||||
"presentation": { |
||||
"order": 1 |
||||
} |
||||
} |
||||
] |
||||
} |
||||
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
{ |
||||
"[typescript]": { |
||||
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||
}, |
||||
"[javascript]": { |
||||
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||
}, |
||||
"[json]": { |
||||
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||
} |
||||
} |
||||
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
MIT License |
||||
|
||||
Copyright (c) 2024 Cody Tseng |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 71 KiB |
@ -1,17 +1,21 @@
@@ -1,17 +1,21 @@
|
||||
{ |
||||
"$schema": "https://ui.shadcn.com/schema.json", |
||||
"style": "default", |
||||
"style": "new-york", |
||||
"rsc": false, |
||||
"tsx": true, |
||||
"tailwind": { |
||||
"config": "tailwind.config.js", |
||||
"css": "src/renderer/src/assets/main.css", |
||||
"baseColor": "slate", |
||||
"css": "src/index.css", |
||||
"baseColor": "zinc", |
||||
"cssVariables": true, |
||||
"prefix": "" |
||||
}, |
||||
"aliases": { |
||||
"components": "@renderer/components", |
||||
"utils": "@renderer/lib/utils" |
||||
} |
||||
"components": "@/components", |
||||
"utils": "@/lib/utils", |
||||
"ui": "@/components/ui", |
||||
"lib": "@/lib", |
||||
"hooks": "@/hooks" |
||||
}, |
||||
"iconLibrary": "lucide" |
||||
} |
||||
|
||||
@ -1,34 +0,0 @@
@@ -1,34 +0,0 @@
|
||||
appId: com.jumble.app |
||||
productName: jumble |
||||
directories: |
||||
buildResources: build |
||||
files: |
||||
- '!**/.vscode/*' |
||||
- '!src/*' |
||||
- '!electron.vite.config.{js,ts,mjs,cjs}' |
||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' |
||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' |
||||
- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' |
||||
asarUnpack: |
||||
- resources/** |
||||
win: |
||||
executableName: jumble |
||||
nsis: |
||||
artifactName: ${name}-${version}-setup.${ext} |
||||
shortcutName: ${productName} |
||||
uninstallDisplayName: ${productName} |
||||
createDesktopShortcut: always |
||||
mac: |
||||
notarize: false |
||||
dmg: |
||||
artifactName: ${name}-${version}.${ext} |
||||
linux: |
||||
target: |
||||
- AppImage |
||||
- snap |
||||
- deb |
||||
maintainer: codytseng |
||||
category: Utility |
||||
appImage: |
||||
artifactName: ${name}-${version}.${ext} |
||||
npmRebuild: false |
||||
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
import { resolve } from 'path' |
||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite' |
||||
import react from '@vitejs/plugin-react' |
||||
|
||||
export default defineConfig({ |
||||
main: { |
||||
plugins: [externalizeDepsPlugin()] |
||||
}, |
||||
preload: { |
||||
plugins: [externalizeDepsPlugin()] |
||||
}, |
||||
renderer: { |
||||
resolve: { |
||||
alias: { |
||||
'@renderer': resolve('src/renderer/src'), |
||||
'@common': resolve('src/common') |
||||
} |
||||
}, |
||||
plugins: [react()] |
||||
} |
||||
}) |
||||
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
import js from '@eslint/js' |
||||
import globals from 'globals' |
||||
import reactHooks from 'eslint-plugin-react-hooks' |
||||
import reactRefresh from 'eslint-plugin-react-refresh' |
||||
import tseslint from 'typescript-eslint' |
||||
|
||||
export default tseslint.config( |
||||
{ ignores: ['dist'] }, |
||||
{ |
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended], |
||||
files: ['**/*.{ts,tsx}'], |
||||
languageOptions: { |
||||
ecmaVersion: 2020, |
||||
globals: globals.browser |
||||
}, |
||||
plugins: { |
||||
'react-hooks': reactHooks, |
||||
'react-refresh': reactRefresh |
||||
}, |
||||
rules: { |
||||
...reactHooks.configs.recommended.rules, |
||||
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], |
||||
'@typescript-eslint/explicit-function-return-type': 'off', |
||||
'react/prop-types': 'off', |
||||
'@typescript-eslint/no-explicit-any': 'off', |
||||
'react-refresh/only-export-components': 'off', |
||||
'react-hooks/exhaustive-deps': 'off' |
||||
} |
||||
} |
||||
) |
||||
@ -1,23 +1,34 @@
@@ -1,23 +1,34 @@
|
||||
<!doctype html> |
||||
<html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<link rel="icon" href="/src/assets/favicon-light.svg" media="(prefers-color-scheme: light)" type="image/svg+xml" /> |
||||
<link rel="icon" href="/src/assets/favicon-dark.svg" media="(prefers-color-scheme: dark)" type="image/svg+xml" /> |
||||
<link |
||||
rel="icon" |
||||
href="/favicon-light.svg" |
||||
media="(prefers-color-scheme: light)" |
||||
type="image/svg+xml" |
||||
/> |
||||
<link |
||||
rel="icon" |
||||
href="/favicon-dark.svg" |
||||
media="(prefers-color-scheme: dark)" |
||||
type="image/svg+xml" |
||||
/> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
|
||||
<meta property="og:url" content="https://jumble.social" /> |
||||
<meta property="og:type" content="website" /> |
||||
<meta property="og:title" content="Jumble" /> |
||||
<meta property="og:description" content="A beautiful nostr client focused on browsing relay feeds" /> |
||||
<meta |
||||
property="og:description" |
||||
content="A beautiful nostr client focused on browsing relay feeds" |
||||
/> |
||||
<meta |
||||
property="og:image" |
||||
content="https://github.com/CodyTseng/jumble/blob/master/resources/og-image.png?raw=true" |
||||
/> |
||||
<title>Jumble</title> |
||||
</head> |
||||
|
||||
<title>Jumble</title> |
||||
|
||||
<body> |
||||
<div id="root"></div> |
||||
<script type="module" src="/src/main.tsx"></script> |
||||
@ -1,3 +1,6 @@
@@ -1,3 +1,6 @@
|
||||
module.exports = { |
||||
plugins: [require('tailwindcss'), require('autoprefixer')] |
||||
export default { |
||||
plugins: { |
||||
tailwindcss: {}, |
||||
autoprefixer: {} |
||||
} |
||||
} |
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 23 KiB |
@ -1,8 +1,8 @@
@@ -1,8 +1,8 @@
|
||||
import 'yet-another-react-lightbox/styles.css' |
||||
import './assets/main.css' |
||||
import './index.css' |
||||
|
||||
import { Toaster } from '@renderer/components/ui/toaster' |
||||
import { ThemeProvider } from '@renderer/providers/ThemeProvider' |
||||
import { Toaster } from '@/components/ui/toaster' |
||||
import { ThemeProvider } from '@/providers/ThemeProvider' |
||||
import { PageManager } from './PageManager' |
||||
import NoteListPage from './pages/primary/NoteListPage' |
||||
import { FollowListProvider } from './providers/FollowListProvider' |
||||
@ -1,59 +0,0 @@
@@ -1,59 +0,0 @@
|
||||
import { ElectronAPI } from '@electron-toolkit/preload' |
||||
import { Event } from 'nostr-tools' |
||||
|
||||
export type TRelayGroup = { |
||||
groupName: string |
||||
relayUrls: string[] |
||||
isActive: boolean |
||||
} |
||||
|
||||
export type TConfig = { |
||||
relayGroups: TRelayGroup[] |
||||
theme: TThemeSetting |
||||
} |
||||
|
||||
export type TThemeSetting = 'light' | 'dark' | 'system' |
||||
export type TTheme = 'light' | 'dark' |
||||
|
||||
export type TDraftEvent = Pick<Event, 'content' | 'created_at' | 'kind' | 'tags'> |
||||
|
||||
export interface ISigner { |
||||
getPublicKey: () => Promise<string | null> |
||||
signEvent: (draftEvent: TDraftEvent) => Promise<Event | null> |
||||
} |
||||
|
||||
export type TElectronWindow = { |
||||
electron: ElectronAPI |
||||
api: { |
||||
system: { |
||||
isEncryptionAvailable: () => Promise<boolean> |
||||
getSelectedStorageBackend: () => Promise<string> |
||||
} |
||||
theme: { |
||||
addChangeListener: (listener: (theme: TTheme) => void) => void |
||||
removeChangeListener: () => void |
||||
current: () => Promise<TTheme> |
||||
} |
||||
storage: { |
||||
getItem: (key: string) => Promise<string> |
||||
setItem: (key: string, value: string) => Promise<void> |
||||
removeItem: (key: string) => Promise<void> |
||||
} |
||||
nostr: { |
||||
login: (nsec: string) => Promise<{ |
||||
pubkey?: string |
||||
reason?: string |
||||
}> |
||||
logout: () => Promise<void> |
||||
} |
||||
} |
||||
nostr: ISigner |
||||
} |
||||
|
||||
export type TAccount = { |
||||
pubkey: string |
||||
signerType: 'nsec' | 'browser-nsec' | 'nip-07' | 'bunker' |
||||
nsec?: string |
||||
bunker?: string |
||||
bunkerClientSecretKey?: string |
||||
} |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import { Button } from '@/components/ui/button' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import { LogIn } from 'lucide-react' |
||||
|
||||
export default function LoginButton({ |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import LoginButton from './LoginButton' |
||||
import ProfileButton from './ProfileButton' |
||||
|
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { useSecondaryPage } from '@renderer/PageManager' |
||||
import { Button } from '@/components/ui/button' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
import { ChevronLeft } from 'lucide-react' |
||||
import { useTranslation } from 'react-i18next' |
||||
|
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { isNsfwEvent } from '@renderer/lib/event' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { isNsfwEvent } from '@/lib/event' |
||||
import { cn } from '@/lib/utils' |
||||
import { Event } from 'nostr-tools' |
||||
import { memo } from 'react' |
||||
import { |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { toNoteList } from '@renderer/lib/link' |
||||
import { SecondaryPageLink } from '@renderer/PageManager' |
||||
import { toNoteList } from '@/lib/link' |
||||
import { SecondaryPageLink } from '@/PageManager' |
||||
import { TEmbeddedRenderer } from './types' |
||||
|
||||
export function EmbeddedHashtag({ hashtag }: { hashtag: string }) { |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { useFetchEvent } from '@renderer/hooks' |
||||
import { toNoStrudelArticle, toNoStrudelNote, toNoStrudelStream } from '@renderer/lib/link' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { useFetchEvent } from '@/hooks' |
||||
import { toNoStrudelArticle, toNoStrudelNote, toNoStrudelStream } from '@/lib/link' |
||||
import { cn } from '@/lib/utils' |
||||
import { kinds } from 'nostr-tools' |
||||
import ShortTextNoteCard from '../NoteCard/ShortTextNoteCard' |
||||
|
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { useSecondaryPage } from '@renderer/PageManager' |
||||
import { toNoteList } from '@renderer/lib/link' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
import { toNoteList } from '@/lib/link' |
||||
import { TEmbeddedRenderer } from './types' |
||||
|
||||
export function EmbeddedWebsocketUrl({ url }: { url: string }) { |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { useToast } from '@renderer/hooks' |
||||
import { useFollowList } from '@renderer/providers/FollowListProvider' |
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import { Button } from '@/components/ui/button' |
||||
import { useToast } from '@/hooks' |
||||
import { useFollowList } from '@/providers/FollowListProvider' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import { Loader } from 'lucide-react' |
||||
import { useMemo, useState } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Image } from '@nextui-org/image' |
||||
import { ScrollArea, ScrollBar } from '@renderer/components/ui/scroll-area' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area' |
||||
import { cn } from '@/lib/utils' |
||||
import { useState } from 'react' |
||||
import Lightbox from 'yet-another-react-lightbox' |
||||
import Zoom from 'yet-another-react-lightbox/plugins/zoom' |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Input } from '@renderer/components/ui/input' |
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import { Button } from '@/components/ui/button' |
||||
import { Input } from '@/components/ui/input' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import { Loader } from 'lucide-react' |
||||
import { useState } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { useFetchNip05 } from '@renderer/hooks/useFetchNip05' |
||||
import { useFetchNip05 } from '@/hooks/useFetchNip05' |
||||
import { BadgeAlert, BadgeCheck } from 'lucide-react' |
||||
|
||||
export default function Nip05({ nip05, pubkey }: { nip05?: string; pubkey: string }) { |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { useSecondaryPage } from '@renderer/PageManager' |
||||
import { toNote } from '@renderer/lib/link' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
import { toNote } from '@/lib/link' |
||||
import { Event } from 'nostr-tools' |
||||
import Content from '../Content' |
||||
import { FormattedTimestamp } from '../FormattedTimestamp' |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import client from '@renderer/services/client.service' |
||||
import client from '@/services/client.service' |
||||
import { Event, kinds, verifyEvent } from 'nostr-tools' |
||||
import { useMemo } from 'react' |
||||
import ShortTextNoteCard from './ShortTextNoteCard' |
||||
@ -1,8 +1,8 @@
@@ -1,8 +1,8 @@
|
||||
import { useFetchEvent } from '@renderer/hooks' |
||||
import { getParentEventId, getRootEventId } from '@renderer/lib/event' |
||||
import { toNote } from '@renderer/lib/link' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { useSecondaryPage } from '@renderer/PageManager' |
||||
import { useFetchEvent } from '@/hooks' |
||||
import { getParentEventId, getRootEventId } from '@/lib/event' |
||||
import { toNote } from '@/lib/link' |
||||
import { cn } from '@/lib/utils' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
import { Repeat2 } from 'lucide-react' |
||||
import { Event } from 'nostr-tools' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,5 +1,4 @@
@@ -1,5 +1,4 @@
|
||||
import { Event } from 'nostr-tools' |
||||
import { kinds } from 'nostr-tools' |
||||
import { Event, kinds } from 'nostr-tools' |
||||
import RepostNoteCard from './RepostNoteCard' |
||||
import ShortTextNoteCard from './ShortTextNoteCard' |
||||
|
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import { useNoteStats } from '@renderer/providers/NoteStatsProvider' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import { useNoteStats } from '@/providers/NoteStatsProvider' |
||||
import { MessageCircle } from 'lucide-react' |
||||
import { Event } from 'nostr-tools' |
||||
import { useMemo, useState } from 'react' |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { cn } from '@renderer/lib/utils' |
||||
import { cn } from '@/lib/utils' |
||||
import { Event } from 'nostr-tools' |
||||
import LikeButton from './LikeButton' |
||||
import NoteOptions from './NoteOptions' |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { toNotifications } from '@renderer/lib/link' |
||||
import { useSecondaryPage } from '@renderer/PageManager' |
||||
import { Button } from '@/components/ui/button' |
||||
import { toNotifications } from '@/lib/link' |
||||
import { useSecondaryPage } from '@/PageManager' |
||||
import { Bell } from 'lucide-react' |
||||
import { useTranslation } from 'react-i18next' |
||||
|
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { cn } from '@renderer/lib/utils' |
||||
import { cn } from '@/lib/utils' |
||||
import { useState } from 'react' |
||||
|
||||
export default function NsfwOverlay({ className }: { className?: string }) { |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
import { cn } from '@/lib/utils' |
||||
import { Event } from 'nostr-tools' |
||||
import UserAvatar from '../UserAvatar' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { useTranslation } from 'react-i18next' |
||||
import UserAvatar from '../UserAvatar' |
||||
|
||||
export default function ParentNotePreview({ |
||||
event, |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import PostDialog from '@renderer/components/PostDialog' |
||||
import { Button } from '@renderer/components/ui/button' |
||||
import PostDialog from '@/components/PostDialog' |
||||
import { Button } from '@/components/ui/button' |
||||
import { PencilLine } from 'lucide-react' |
||||
import { useState } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { Card } from '@renderer/components/ui/card' |
||||
import { Card } from '@/components/ui/card' |
||||
import dayjs from 'dayjs' |
||||
import Content from '../Content' |
||||
|
||||
@ -1,17 +1,17 @@
@@ -1,17 +1,17 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Button } from '@/components/ui/button' |
||||
import { |
||||
Dialog, |
||||
DialogContent, |
||||
DialogDescription, |
||||
DialogHeader, |
||||
DialogTitle |
||||
} from '@renderer/components/ui/dialog' |
||||
import { ScrollArea } from '@renderer/components/ui/scroll-area' |
||||
import { Textarea } from '@renderer/components/ui/textarea' |
||||
import { useToast } from '@renderer/hooks/use-toast' |
||||
import { createShortTextNoteDraftEvent } from '@renderer/lib/draft-event' |
||||
import { useNostr } from '@renderer/providers/NostrProvider' |
||||
import client from '@renderer/services/client.service' |
||||
} from '@/components/ui/dialog' |
||||
import { ScrollArea } from '@/components/ui/scroll-area' |
||||
import { Textarea } from '@/components/ui/textarea' |
||||
import { useToast } from '@/hooks/use-toast' |
||||
import { createShortTextNoteDraftEvent } from '@/lib/draft-event' |
||||
import { useNostr } from '@/providers/NostrProvider' |
||||
import client from '@/services/client.service' |
||||
import { LoaderCircle } from 'lucide-react' |
||||
import { Event } from 'nostr-tools' |
||||
import { Dispatch, useState } from 'react' |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Image } from '@nextui-org/image' |
||||
import { generateImageByPubkey } from '@renderer/lib/pubkey' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { generateImageByPubkey } from '@/lib/pubkey' |
||||
import { cn } from '@/lib/utils' |
||||
import { useEffect, useMemo, useState } from 'react' |
||||
|
||||
export default function ProfileBanner({ |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@renderer/components/ui/avatar' |
||||
import { useFetchProfile } from '@renderer/hooks' |
||||
import { generateImageByPubkey } from '@renderer/lib/pubkey' |
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' |
||||
import { useFetchProfile } from '@/hooks' |
||||
import { generateImageByPubkey } from '@/lib/pubkey' |
||||
import { useMemo } from 'react' |
||||
import FollowButton from '../FollowButton' |
||||
import Nip05 from '../Nip05' |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { usePrimaryPage } from '@renderer/PageManager' |
||||
import { Button } from '@/components/ui/button' |
||||
import { usePrimaryPage } from '@/PageManager' |
||||
import { RefreshCcw } from 'lucide-react' |
||||
import { useTranslation } from 'react-i18next' |
||||
|
||||
@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Button } from '@/components/ui/button' |
||||
import { |
||||
DropdownMenu, |
||||
DropdownMenuContent, |
||||
DropdownMenuItem, |
||||
DropdownMenuTrigger |
||||
} from '@renderer/components/ui/dropdown-menu' |
||||
import { Input } from '@renderer/components/ui/input' |
||||
import { useRelaySettings } from '@renderer/providers/RelaySettingsProvider' |
||||
} from '@/components/ui/dropdown-menu' |
||||
import { Input } from '@/components/ui/input' |
||||
import { useRelaySettings } from '@/providers/RelaySettingsProvider' |
||||
import { Check, ChevronDown, Circle, CircleCheck, EllipsisVertical } from 'lucide-react' |
||||
import { useState } from 'react' |
||||
import RelayUrls from './RelayUrl' |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { useFetchRelayInfos } from '@renderer/hooks' |
||||
import { useRelaySettings } from '@renderer/providers/RelaySettingsProvider' |
||||
import client from '@renderer/services/client.service' |
||||
import { Button } from '@/components/ui/button' |
||||
import { useFetchRelayInfos } from '@/hooks' |
||||
import { useRelaySettings } from '@/providers/RelaySettingsProvider' |
||||
import client from '@/services/client.service' |
||||
import { Save, SearchCheck } from 'lucide-react' |
||||
import { useEffect, useState } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Input } from '@renderer/components/ui/input' |
||||
import { Separator } from '@renderer/components/ui/separator' |
||||
import { useRelaySettings } from '@renderer/providers/RelaySettingsProvider' |
||||
import { Button } from '@/components/ui/button' |
||||
import { Input } from '@/components/ui/input' |
||||
import { Separator } from '@/components/ui/separator' |
||||
import { useRelaySettings } from '@/providers/RelaySettingsProvider' |
||||
import { useEffect, useRef, useState } from 'react' |
||||
import { RelaySettingsComponentProvider } from './provider' |
||||
import RelayGroup from './RelayGroup' |
||||
@ -1,10 +1,10 @@
@@ -1,10 +1,10 @@
|
||||
import RelaySettings from '@renderer/components/RelaySettings' |
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover' |
||||
import { ScrollArea } from '@renderer/components/ui/scroll-area' |
||||
import { toRelaySettings } from '@renderer/lib/link' |
||||
import { SecondaryPageLink } from '@renderer/PageManager' |
||||
import { useScreenSize } from '@renderer/providers/ScreenSizeProvider' |
||||
import RelaySettings from '@/components/RelaySettings' |
||||
import { Button } from '@/components/ui/button' |
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' |
||||
import { ScrollArea } from '@/components/ui/scroll-area' |
||||
import { toRelaySettings } from '@/lib/link' |
||||
import { SecondaryPageLink } from '@/PageManager' |
||||
import { useScreenSize } from '@/providers/ScreenSizeProvider' |
||||
import { Server } from 'lucide-react' |
||||
import { useTranslation } from 'react-i18next' |
||||
|
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { Button } from '@/components/ui/button' |
||||
import { cn } from '@/lib/utils' |
||||
import { ChevronUp } from 'lucide-react' |
||||
|
||||
export default function ScrollToTopButton({ |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { Button } from '@/components/ui/button' |
||||
import { Search } from 'lucide-react' |
||||
import { useState } from 'react' |
||||
import { useTranslation } from 'react-i18next' |
||||
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
||||
import { Button } from '@renderer/components/ui/button' |
||||
import { useTheme } from '@renderer/providers/ThemeProvider' |
||||
import { Button } from '@/components/ui/button' |
||||
import { useTheme } from '@/providers/ThemeProvider' |
||||
import { Moon, Sun, SunMoon } from 'lucide-react' |
||||
import { useTranslation } from 'react-i18next' |
||||
|
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
import { cn } from '@/lib/utils' |
||||
|
||||
export function Titlebar({ |
||||
children, |
||||
className, |
||||
visible = true |
||||
}: { |
||||
children?: React.ReactNode |
||||
className?: string |
||||
visible?: boolean |
||||
}) { |
||||
return ( |
||||
<div |
||||
className={cn( |
||||
'absolute top-0 w-full h-9 max-sm:h-11 z-50 bg-background/80 backdrop-blur-md flex items-center font-semibold gap-1 px-2 duration-700 transition-transform', |
||||
visible ? '' : '-translate-y-full', |
||||
className |
||||
)} |
||||
> |
||||
{children} |
||||
</div> |
||||
) |
||||
} |
||||
@ -1,11 +1,11 @@
@@ -1,11 +1,11 @@
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@renderer/components/ui/avatar' |
||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@renderer/components/ui/hover-card' |
||||
import { Skeleton } from '@renderer/components/ui/skeleton' |
||||
import { useFetchProfile } from '@renderer/hooks' |
||||
import { generateImageByPubkey } from '@renderer/lib/pubkey' |
||||
import { toProfile } from '@renderer/lib/link' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { SecondaryPageLink } from '@renderer/PageManager' |
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' |
||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card' |
||||
import { Skeleton } from '@/components/ui/skeleton' |
||||
import { useFetchProfile } from '@/hooks' |
||||
import { generateImageByPubkey } from '@/lib/pubkey' |
||||
import { toProfile } from '@/lib/link' |
||||
import { cn } from '@/lib/utils' |
||||
import { SecondaryPageLink } from '@/PageManager' |
||||
import ProfileCard from '../ProfileCard' |
||||
import { useMemo } from 'react' |
||||
|
||||
@ -1,8 +1,8 @@
@@ -1,8 +1,8 @@
|
||||
import FollowButton from '@renderer/components/FollowButton' |
||||
import Nip05 from '@renderer/components/Nip05' |
||||
import UserAvatar from '@renderer/components/UserAvatar' |
||||
import Username from '@renderer/components/Username' |
||||
import { useFetchProfile } from '@renderer/hooks' |
||||
import FollowButton from '@/components/FollowButton' |
||||
import Nip05 from '@/components/Nip05' |
||||
import UserAvatar from '@/components/UserAvatar' |
||||
import Username from '@/components/Username' |
||||
import { useFetchProfile } from '@/hooks' |
||||
|
||||
export default function UserItem({ pubkey }: { pubkey: string }) { |
||||
const { profile } = useFetchProfile(pubkey) |
||||
@ -1,9 +1,9 @@
@@ -1,9 +1,9 @@
|
||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@renderer/components/ui/hover-card' |
||||
import { Skeleton } from '@renderer/components/ui/skeleton' |
||||
import { useFetchProfile } from '@renderer/hooks' |
||||
import { toProfile } from '@renderer/lib/link' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { SecondaryPageLink } from '@renderer/PageManager' |
||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card' |
||||
import { Skeleton } from '@/components/ui/skeleton' |
||||
import { useFetchProfile } from '@/hooks' |
||||
import { toProfile } from '@/lib/link' |
||||
import { cn } from '@/lib/utils' |
||||
import { SecondaryPageLink } from '@/PageManager' |
||||
import ProfileCard from '../ProfileCard' |
||||
|
||||
export default function Username({ |
||||
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
import { cn } from '@renderer/lib/utils' |
||||
import { cn } from '@/lib/utils' |
||||
import NsfwOverlay from '../NsfwOverlay' |
||||
|
||||
export default function VideoPlayer({ |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Image } from '@nextui-org/image' |
||||
import { useFetchWebMetadata } from '@renderer/hooks/useFetchWebMetadata' |
||||
import { cn } from '@renderer/lib/utils' |
||||
import { useFetchWebMetadata } from '@/hooks/useFetchWebMetadata' |
||||
import { cn } from '@/lib/utils' |
||||
import { useMemo } from 'react' |
||||
|
||||
export default function WebPreview({ |
||||