Merge pull request #132 from luminous-devs/feat/universal-titlebar
feat: add window titlebar
This commit is contained in:
@@ -81,7 +81,6 @@
|
|||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-string-replace": "^1.1.1",
|
"react-string-replace": "^1.1.1",
|
||||||
"sonner": "^1.2.4",
|
"sonner": "^1.2.4",
|
||||||
"tauri-controls": "github:reyamir/tauri-controls",
|
|
||||||
"tippy.js": "^6.3.7",
|
"tippy.js": "^6.3.7",
|
||||||
"tiptap-markdown": "^0.8.8",
|
"tiptap-markdown": "^0.8.8",
|
||||||
"virtua": "^0.17.5",
|
"virtua": "^0.17.5",
|
||||||
|
|||||||
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@@ -194,9 +194,6 @@ dependencies:
|
|||||||
sonner:
|
sonner:
|
||||||
specifier: ^1.2.4
|
specifier: ^1.2.4
|
||||||
version: 1.2.4(react-dom@18.2.0)(react@18.2.0)
|
version: 1.2.4(react-dom@18.2.0)(react@18.2.0)
|
||||||
tauri-controls:
|
|
||||||
specifier: github:reyamir/tauri-controls
|
|
||||||
version: github.com/reyamir/tauri-controls/079b1262f9b75c84b97613174836101b01d61c37(@tauri-apps/api@2.0.0-alpha.11)(@tauri-apps/plugin-os@2.0.0-alpha.4)(clsx@2.0.0)(react-dom@18.2.0)(react@18.2.0)(tailwind-merge@1.14.0)
|
|
||||||
tippy.js:
|
tippy.js:
|
||||||
specifier: ^6.3.7
|
specifier: ^6.3.7
|
||||||
version: 6.3.7
|
version: 6.3.7
|
||||||
@@ -3135,6 +3132,7 @@ packages:
|
|||||||
/clsx@2.0.0:
|
/clsx@2.0.0:
|
||||||
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
|
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/color-convert@1.9.3:
|
/color-convert@1.9.3:
|
||||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||||
@@ -5689,6 +5687,7 @@ packages:
|
|||||||
|
|
||||||
/tailwind-merge@1.14.0:
|
/tailwind-merge@1.14.0:
|
||||||
resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==}
|
resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tailwind-scrollbar@3.0.5(tailwindcss@3.3.6):
|
/tailwind-scrollbar@3.0.5(tailwindcss@3.3.6):
|
||||||
resolution: {integrity: sha512-0ZwxTivevqq9BY9fRP9zDjHl7Tu+J5giBGbln+0O1R/7nHtBUKnjQcA1aTIhK7Oyjp6Uc/Dj6/dn8Dq58k5Uww==}
|
resolution: {integrity: sha512-0ZwxTivevqq9BY9fRP9zDjHl7Tu+J5giBGbln+0O1R/7nHtBUKnjQcA1aTIhK7Oyjp6Uc/Dj6/dn8Dq58k5Uww==}
|
||||||
@@ -6214,24 +6213,3 @@ packages:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
github.com/reyamir/tauri-controls/079b1262f9b75c84b97613174836101b01d61c37(@tauri-apps/api@2.0.0-alpha.11)(@tauri-apps/plugin-os@2.0.0-alpha.4)(clsx@2.0.0)(react-dom@18.2.0)(react@18.2.0)(tailwind-merge@1.14.0):
|
|
||||||
resolution: {tarball: https://codeload.github.com/reyamir/tauri-controls/tar.gz/079b1262f9b75c84b97613174836101b01d61c37}
|
|
||||||
id: github.com/reyamir/tauri-controls/079b1262f9b75c84b97613174836101b01d61c37
|
|
||||||
name: tauri-controls
|
|
||||||
version: 0.3.0
|
|
||||||
peerDependencies:
|
|
||||||
'@tauri-apps/api': ^2.0.0-alpha.11
|
|
||||||
'@tauri-apps/plugin-os': ^2.0.0-alpha.3
|
|
||||||
clsx: ^2.0.0
|
|
||||||
react: ^18.2.0
|
|
||||||
react-dom: ^18.2.0
|
|
||||||
tailwind-merge: ^1.14.0
|
|
||||||
dependencies:
|
|
||||||
'@tauri-apps/api': 2.0.0-alpha.11
|
|
||||||
'@tauri-apps/plugin-os': 2.0.0-alpha.4
|
|
||||||
clsx: 2.0.0
|
|
||||||
react: 18.2.0
|
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
|
||||||
tailwind-merge: 1.14.0
|
|
||||||
dev: false
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
import { WindowTitlebar } from 'tauri-controls';
|
|
||||||
|
|
||||||
import { useArk } from '@libs/ark';
|
import { useArk } from '@libs/ark';
|
||||||
|
|
||||||
import { Navigation } from '@shared/navigation';
|
import { Navigation } from '@shared/navigation';
|
||||||
|
import { WindowTitleBar } from '@shared/titlebar';
|
||||||
|
|
||||||
export function AppLayout() {
|
export function AppLayout() {
|
||||||
const { ark } = useArk();
|
const { ark } = useArk();
|
||||||
@@ -17,7 +17,7 @@ export function AppLayout() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{ark.platform !== 'macos' ? (
|
{ark.platform !== 'macos' ? (
|
||||||
<WindowTitlebar />
|
<WindowTitleBar platform={ark.platform} />
|
||||||
) : (
|
) : (
|
||||||
<div data-tauri-drag-region className="h-9" />
|
<div data-tauri-drag-region className="h-9" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
||||||
import { WindowTitlebar } from 'tauri-controls';
|
|
||||||
|
|
||||||
import { useArk } from '@libs/ark';
|
import { useArk } from '@libs/ark';
|
||||||
|
|
||||||
|
import { WindowTitleBar } from '@shared/titlebar';
|
||||||
|
|
||||||
export function AuthLayout() {
|
export function AuthLayout() {
|
||||||
const { ark } = useArk();
|
const { ark } = useArk();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-screen flex-col">
|
<div className="flex h-screen w-screen flex-col">
|
||||||
{ark.platform !== 'macos' ? (
|
{ark.platform !== 'macos' ? (
|
||||||
<WindowTitlebar />
|
<WindowTitleBar platform={ark.platform} />
|
||||||
) : (
|
) : (
|
||||||
<div data-tauri-drag-region className="h-9" />
|
<div data-tauri-drag-region className="h-9" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Link, NavLink, Outlet, useLocation } from 'react-router-dom';
|
import { Link, NavLink, Outlet, useLocation } from 'react-router-dom';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
import { WindowTitlebar } from 'tauri-controls';
|
|
||||||
|
|
||||||
import { useArk } from '@libs/ark';
|
import { useArk } from '@libs/ark';
|
||||||
|
|
||||||
import { ArrowLeftIcon } from '@shared/icons';
|
import { ArrowLeftIcon } from '@shared/icons';
|
||||||
|
import { WindowTitleBar } from '@shared/titlebar';
|
||||||
|
|
||||||
export function NewLayout() {
|
export function NewLayout() {
|
||||||
const { ark } = useArk();
|
const { ark } = useArk();
|
||||||
@@ -13,7 +13,7 @@ export function NewLayout() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
||||||
{ark.platform !== 'macos' ? (
|
{ark.platform !== 'macos' ? (
|
||||||
<WindowTitlebar />
|
<WindowTitleBar platform={ark.platform} />
|
||||||
) : (
|
) : (
|
||||||
<div data-tauri-drag-region className="h-9 shrink-0" />
|
<div data-tauri-drag-region className="h-9 shrink-0" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
import { Outlet, ScrollRestoration } from 'react-router-dom';
|
||||||
import { WindowTitlebar } from 'tauri-controls';
|
|
||||||
|
|
||||||
import { useArk } from '@libs/ark';
|
import { useArk } from '@libs/ark';
|
||||||
|
|
||||||
|
import { WindowTitleBar } from '@shared/titlebar';
|
||||||
|
|
||||||
export function NoteLayout() {
|
export function NoteLayout() {
|
||||||
const { ark } = useArk();
|
const { ark } = useArk();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
||||||
{ark.platform !== 'macos' ? (
|
{ark.platform !== 'macos' ? (
|
||||||
<WindowTitlebar />
|
<WindowTitleBar platform={ark.platform} />
|
||||||
) : (
|
) : (
|
||||||
<div data-tauri-drag-region className="h-9" />
|
<div data-tauri-drag-region className="h-9" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { NavLink, Outlet, ScrollRestoration, useNavigate } from 'react-router-dom';
|
import { NavLink, Outlet, ScrollRestoration, useNavigate } from 'react-router-dom';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
import { WindowTitlebar } from 'tauri-controls';
|
|
||||||
|
|
||||||
import { useArk } from '@libs/ark';
|
import { useArk } from '@libs/ark';
|
||||||
|
|
||||||
@@ -12,6 +11,7 @@ import {
|
|||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
} from '@shared/icons';
|
} from '@shared/icons';
|
||||||
|
import { WindowTitleBar } from '@shared/titlebar';
|
||||||
|
|
||||||
export function SettingsLayout() {
|
export function SettingsLayout() {
|
||||||
const { ark } = useArk();
|
const { ark } = useArk();
|
||||||
@@ -20,7 +20,7 @@ export function SettingsLayout() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
<div className="flex h-screen w-screen flex-col bg-neutral-50 dark:bg-neutral-950">
|
||||||
{ark.platform !== 'macos' ? (
|
{ark.platform !== 'macos' ? (
|
||||||
<WindowTitlebar />
|
<WindowTitleBar platform={ark.platform} />
|
||||||
) : (
|
) : (
|
||||||
<div data-tauri-drag-region className="h-9" />
|
<div data-tauri-drag-region className="h-9" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
20
src/shared/titlebar/components/button.tsx
Normal file
20
src/shared/titlebar/components/button.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { ButtonHTMLAttributes } from 'react';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
export function WindowButton({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: ButtonHTMLAttributes<HTMLButtonElement>) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={twMerge(
|
||||||
|
'inline-flex cursor-default items-center justify-center',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
140
src/shared/titlebar/components/icons.tsx
Normal file
140
src/shared/titlebar/components/icons.tsx
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import type { SVGProps } from 'react';
|
||||||
|
|
||||||
|
export const WindowIcons = {
|
||||||
|
minimizeWin: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="10"
|
||||||
|
height="1"
|
||||||
|
viewBox="0 0 10 1"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M0.498047 1.00098C0.429688 1.00098 0.364583 0.987956 0.302734 0.961914C0.244141 0.935872 0.192057 0.900065 0.146484 0.854492C0.100911 0.808919 0.0651042 0.756836 0.0390625 0.698242C0.0130208 0.636393 0 0.571289 0 0.50293C0 0.43457 0.0130208 0.371094 0.0390625 0.3125C0.0651042 0.250651 0.100911 0.19694 0.146484 0.151367C0.192057 0.102539 0.244141 0.0651042 0.302734 0.0390625C0.364583 0.0130208 0.429688 0 0.498047 0H9.50195C9.57031 0 9.63379 0.0130208 9.69238 0.0390625C9.75423 0.0651042 9.80794 0.102539 9.85352 0.151367C9.89909 0.19694 9.9349 0.250651 9.96094 0.3125C9.98698 0.371094 10 0.43457 10 0.50293C10 0.571289 9.98698 0.636393 9.96094 0.698242C9.9349 0.756836 9.89909 0.808919 9.85352 0.854492C9.80794 0.900065 9.75423 0.935872 9.69238 0.961914C9.63379 0.987956 9.57031 1.00098 9.50195 1.00098H0.498047Z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillOpacity="0.8956"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
maximizeWin: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="10"
|
||||||
|
height="10"
|
||||||
|
viewBox="0 0 10 10"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1.47461 10.001C1.2793 10.001 1.09212 9.96191 0.913086 9.88379C0.734049 9.80241 0.576172 9.69499 0.439453 9.56152C0.30599 9.4248 0.198568 9.26693 0.117188 9.08789C0.0390625 8.90885 0 8.72168 0 8.52637V1.47559C0 1.28027 0.0390625 1.0931 0.117188 0.914062C0.198568 0.735026 0.30599 0.578776 0.439453 0.445312C0.576172 0.308594 0.734049 0.201172 0.913086 0.123047C1.09212 0.0416667 1.2793 0.000976562 1.47461 0.000976562H8.52539C8.7207 0.000976562 8.90788 0.0416667 9.08691 0.123047C9.26595 0.201172 9.4222 0.308594 9.55566 0.445312C9.69238 0.578776 9.7998 0.735026 9.87793 0.914062C9.95931 1.0931 10 1.28027 10 1.47559V8.52637C10 8.72168 9.95931 8.90885 9.87793 9.08789C9.7998 9.26693 9.69238 9.4248 9.55566 9.56152C9.4222 9.69499 9.26595 9.80241 9.08691 9.88379C8.90788 9.96191 8.7207 10.001 8.52539 10.001H1.47461ZM8.50098 9C8.56934 9 8.63281 8.98698 8.69141 8.96094C8.75326 8.9349 8.80697 8.89909 8.85254 8.85352C8.89811 8.80794 8.93392 8.75586 8.95996 8.69727C8.986 8.63542 8.99902 8.57031 8.99902 8.50195V1.5C8.99902 1.43164 8.986 1.36816 8.95996 1.30957C8.93392 1.24772 8.89811 1.19401 8.85254 1.14844C8.80697 1.10286 8.75326 1.06706 8.69141 1.04102C8.63281 1.01497 8.56934 1.00195 8.50098 1.00195H1.49902C1.43066 1.00195 1.36556 1.01497 1.30371 1.04102C1.24512 1.06706 1.19303 1.10286 1.14746 1.14844C1.10189 1.19401 1.06608 1.24772 1.04004 1.30957C1.014 1.36816 1.00098 1.43164 1.00098 1.5V8.50195C1.00098 8.57031 1.014 8.63542 1.04004 8.69727C1.06608 8.75586 1.10189 8.80794 1.14746 8.85352C1.19303 8.89909 1.24512 8.9349 1.30371 8.96094C1.36556 8.98698 1.43066 9 1.49902 9H8.50098Z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillOpacity="0.8956"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
maximizeRestoreWin: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="10"
|
||||||
|
height="11"
|
||||||
|
viewBox="0 0 10 11"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.99902 2.98096C8.99902 2.71077 8.94531 2.45687 8.83789 2.21924C8.73047 1.97835 8.58398 1.77002 8.39844 1.59424C8.21615 1.4152 8.00293 1.27523 7.75879 1.17432C7.5179 1.07015 7.264 1.01807 6.99707 1.01807H2.08496C2.13704 0.868327 2.21029 0.731608 2.30469 0.60791C2.39909 0.484212 2.50814 0.378418 2.63184 0.290527C2.75553 0.202637 2.89062 0.135905 3.03711 0.090332C3.18685 0.0415039 3.34147 0.0170898 3.50098 0.0170898H6.99707C7.41048 0.0170898 7.79948 0.0968424 8.16406 0.256348C8.52865 0.412598 8.84603 0.625814 9.11621 0.895996C9.38965 1.16618 9.60449 1.48356 9.76074 1.84814C9.92025 2.21273 10 2.60173 10 3.01514V6.51611C10 6.67562 9.97559 6.83024 9.92676 6.97998C9.88118 7.12646 9.81445 7.26156 9.72656 7.38525C9.63867 7.50895 9.53288 7.618 9.40918 7.7124C9.28548 7.8068 9.14876 7.88005 8.99902 7.93213V2.98096ZM1.47461 10.0171C1.2793 10.0171 1.09212 9.97803 0.913086 9.8999C0.734049 9.81852 0.576172 9.7111 0.439453 9.57764C0.30599 9.44092 0.198568 9.28304 0.117188 9.104C0.0390625 8.92497 0 8.73779 0 8.54248V3.49365C0 3.29508 0.0390625 3.10791 0.117188 2.93213C0.198568 2.75309 0.30599 2.59684 0.439453 2.46338C0.576172 2.32666 0.732422 2.21924 0.908203 2.14111C1.08724 2.05973 1.27604 2.01904 1.47461 2.01904H6.52344C6.72201 2.01904 6.91081 2.05973 7.08984 2.14111C7.26888 2.21924 7.42513 2.32503 7.55859 2.4585C7.69206 2.59196 7.79785 2.74821 7.87598 2.92725C7.95736 3.10628 7.99805 3.29508 7.99805 3.49365V8.54248C7.99805 8.74105 7.95736 8.92985 7.87598 9.10889C7.79785 9.28467 7.69043 9.44092 7.55371 9.57764C7.42025 9.7111 7.264 9.81852 7.08496 9.8999C6.90918 9.97803 6.72201 10.0171 6.52344 10.0171H1.47461ZM6.49902 9.01611C6.56738 9.01611 6.63086 9.00309 6.68945 8.97705C6.7513 8.95101 6.80501 8.9152 6.85059 8.86963C6.89941 8.82406 6.93685 8.77197 6.96289 8.71338C6.98893 8.65153 7.00195 8.58643 7.00195 8.51807V3.51807C7.00195 3.44971 6.98893 3.3846 6.96289 3.32275C6.93685 3.2609 6.90104 3.20719 6.85547 3.16162C6.8099 3.11605 6.75618 3.08024 6.69434 3.0542C6.63249 3.02816 6.56738 3.01514 6.49902 3.01514H1.49902C1.43066 3.01514 1.36556 3.02816 1.30371 3.0542C1.24512 3.08024 1.19303 3.11768 1.14746 3.1665C1.10189 3.21208 1.06608 3.26579 1.04004 3.32764C1.014 3.38623 1.00098 3.44971 1.00098 3.51807V8.51807C1.00098 8.58643 1.014 8.65153 1.04004 8.71338C1.06608 8.77197 1.10189 8.82406 1.14746 8.86963C1.19303 8.9152 1.24512 8.95101 1.30371 8.97705C1.36556 9.00309 1.43066 9.01611 1.49902 9.01611H6.49902Z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillOpacity="0.8956"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
closeWin: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="10"
|
||||||
|
height="10"
|
||||||
|
viewBox="0 0 10 10"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 5.70898L0.854492 9.85449C0.756836 9.95215 0.639648 10.001 0.50293 10.001C0.359701 10.001 0.239258 9.95378 0.141602 9.85938C0.0472005 9.76172 0 9.64128 0 9.49805C0 9.36133 0.0488281 9.24414 0.146484 9.14648L4.29199 5.00098L0.146484 0.855469C0.0488281 0.757812 0 0.638997 0 0.499023C0 0.430664 0.0130208 0.36556 0.0390625 0.303711C0.0651042 0.241862 0.100911 0.189779 0.146484 0.147461C0.192057 0.101888 0.245768 0.0660807 0.307617 0.0400391C0.369466 0.0139974 0.43457 0.000976562 0.50293 0.000976562C0.639648 0.000976562 0.756836 0.0498047 0.854492 0.147461L5 4.29297L9.14551 0.147461C9.24316 0.0498047 9.36198 0.000976562 9.50195 0.000976562C9.57031 0.000976562 9.63379 0.0139974 9.69238 0.0400391C9.75423 0.0660807 9.80794 0.101888 9.85352 0.147461C9.89909 0.193034 9.9349 0.246745 9.96094 0.308594C9.98698 0.367188 10 0.430664 10 0.499023C10 0.638997 9.95117 0.757812 9.85352 0.855469L5.70801 5.00098L9.85352 9.14648C9.95117 9.24414 10 9.36133 10 9.49805C10 9.56641 9.98698 9.63151 9.96094 9.69336C9.9349 9.75521 9.89909 9.80892 9.85352 9.85449C9.8112 9.90007 9.75911 9.93587 9.69727 9.96191C9.63542 9.98796 9.57031 10.001 9.50195 10.001C9.36198 10.001 9.24316 9.95215 9.14551 9.85449L5 5.70898Z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillOpacity="0.8956"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
closeMac: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="6"
|
||||||
|
height="6"
|
||||||
|
viewBox="0 0 16 18"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M15.7522 4.44381L11.1543 9.04165L15.7494 13.6368C16.0898 13.9771 16.078 14.5407 15.724 14.8947L13.8907 16.728C13.5358 17.0829 12.9731 17.0938 12.6328 16.7534L8.03766 12.1583L3.44437 16.7507C3.10402 17.091 2.54132 17.0801 2.18645 16.7253L0.273257 14.8121C-0.0807018 14.4572 -0.0925004 13.8945 0.247845 13.5542L4.84024 8.96087L0.32499 4.44653C-0.0153555 4.10619 -0.00355681 3.54258 0.350402 3.18862L2.18373 1.35529C2.53859 1.00042 3.1013 0.989533 3.44164 1.32988L7.95689 5.84422L12.5556 1.24638C12.8951 0.906035 13.4587 0.917833 13.8126 1.27179L15.7267 3.18589C16.0807 3.53985 16.0925 4.10346 15.7522 4.44381Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
minMac: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
viewBox="0 0 17 6"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<g clipPath="url(#clip0_20_2051)">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M1.47211 1.18042H15.4197C15.8052 1.18042 16.1179 1.50551 16.1179 1.90769V3.73242C16.1179 4.13387 15.8052 4.80006 15.4197 4.80006H1.47211C1.08665 4.80006 0.773926 4.47497 0.773926 4.07278V1.90769C0.773926 1.50551 1.08665 1.18042 1.47211 1.18042Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
fullMac: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="6"
|
||||||
|
height="6"
|
||||||
|
viewBox="0 0 15 15"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<g clipPath="url(#clip0_20_2057)">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M3.53068 0.433838L15.0933 12.0409C15.0933 12.0409 15.0658 5.35028 15.0658 4.01784C15.0658 1.32095 14.1813 0.433838 11.5378 0.433838C10.6462 0.433838 3.53068 0.433838 3.53068 0.433838ZM12.4409 15.5378L0.87735 3.93073C0.87735 3.93073 0.905794 10.6214 0.905794 11.9538C0.905794 14.6507 1.79024 15.5378 4.43291 15.5378C5.32535 15.5378 12.4409 15.5378 12.4409 15.5378Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
plusMac: (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
width="8"
|
||||||
|
height="8"
|
||||||
|
viewBox="0 0 17 16"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<g clipPath="url(#clip0_20_2053)">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M15.5308 9.80147H10.3199V15.0095C10.3199 15.3949 9.9941 15.7076 9.59265 15.7076H7.51555C7.11337 15.7076 6.78828 15.3949 6.78828 15.0095V9.80147H1.58319C1.19774 9.80147 0.88501 9.47638 0.88501 9.07419V6.90619C0.88501 6.50401 1.19774 6.17892 1.58319 6.17892H6.78828V1.06183C6.78828 0.676375 7.11337 0.363647 7.51555 0.363647H9.59265C9.9941 0.363647 10.3199 0.676375 10.3199 1.06183V6.17892H15.5308C15.9163 6.17892 16.229 6.50401 16.229 6.90619V9.07419C16.229 9.47638 15.9163 9.80147 15.5308 9.80147Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
};
|
||||||
113
src/shared/titlebar/context.tsx
Normal file
113
src/shared/titlebar/context.tsx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { type Window, getCurrent } from '@tauri-apps/api/window';
|
||||||
|
import { type } from '@tauri-apps/plugin-os';
|
||||||
|
import React, { createContext, useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
interface AppWindowContextType {
|
||||||
|
appWindow: Window | null;
|
||||||
|
isWindowMaximized: boolean;
|
||||||
|
minimizeWindow: () => Promise<void>;
|
||||||
|
maximizeWindow: () => Promise<void>;
|
||||||
|
fullscreenWindow: () => Promise<void>;
|
||||||
|
closeWindow: () => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppWindowContext = createContext<AppWindowContextType>({
|
||||||
|
appWindow: null,
|
||||||
|
isWindowMaximized: false,
|
||||||
|
minimizeWindow: () => Promise.resolve(),
|
||||||
|
maximizeWindow: () => Promise.resolve(),
|
||||||
|
fullscreenWindow: () => Promise.resolve(),
|
||||||
|
closeWindow: () => Promise.resolve(),
|
||||||
|
});
|
||||||
|
|
||||||
|
interface AppWindowProviderProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppWindowProvider: React.FC<AppWindowProviderProps> = ({ children }) => {
|
||||||
|
const [appWindow, setAppWindow] = useState<Window | null>(null);
|
||||||
|
const [isWindowMaximized, setIsWindowMaximized] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const window = getCurrent();
|
||||||
|
setAppWindow(window);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const updateIsWindowMaximized = useCallback(async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
const _isWindowMaximized = await appWindow.isMaximized();
|
||||||
|
setIsWindowMaximized(_isWindowMaximized);
|
||||||
|
}
|
||||||
|
}, [appWindow]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let unlisten: () => void = () => {};
|
||||||
|
|
||||||
|
async function getOsType() {
|
||||||
|
const osname = await type();
|
||||||
|
|
||||||
|
if (osname !== 'macos') {
|
||||||
|
updateIsWindowMaximized();
|
||||||
|
|
||||||
|
const listen = async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
unlisten = await appWindow.onResized(() => {
|
||||||
|
updateIsWindowMaximized();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
listen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getOsType();
|
||||||
|
|
||||||
|
// Cleanup the listener when the component unmounts
|
||||||
|
return () => unlisten && unlisten();
|
||||||
|
}, [appWindow, updateIsWindowMaximized]);
|
||||||
|
|
||||||
|
const minimizeWindow = async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
await appWindow.minimize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const maximizeWindow = async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
await appWindow.toggleMaximize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fullscreenWindow = async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
const fullscreen = await appWindow.isFullscreen();
|
||||||
|
if (fullscreen) {
|
||||||
|
await appWindow.setFullscreen(false);
|
||||||
|
} else {
|
||||||
|
await appWindow.setFullscreen(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeWindow = async () => {
|
||||||
|
if (appWindow) {
|
||||||
|
await appWindow.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppWindowContext.Provider
|
||||||
|
value={{
|
||||||
|
appWindow,
|
||||||
|
isWindowMaximized,
|
||||||
|
minimizeWindow,
|
||||||
|
maximizeWindow,
|
||||||
|
fullscreenWindow,
|
||||||
|
closeWindow,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</AppWindowContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
39
src/shared/titlebar/controls/gnome.tsx
Normal file
39
src/shared/titlebar/controls/gnome.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { HTMLProps, useContext } from 'react';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
import { AppWindowContext, WindowButton, WindowIcons } from '@shared/titlebar';
|
||||||
|
|
||||||
|
export function Gnome({ className, ...props }: HTMLProps<HTMLDivElement>) {
|
||||||
|
const { isWindowMaximized, minimizeWindow, maximizeWindow, closeWindow } =
|
||||||
|
useContext(AppWindowContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={twMerge('mr-[10px] h-auto items-center space-x-[13px]', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<WindowButton
|
||||||
|
onClick={minimizeWindow}
|
||||||
|
className="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
|
||||||
|
>
|
||||||
|
<WindowIcons.minimizeWin className="h-[9px] w-[9px]" />
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
onClick={maximizeWindow}
|
||||||
|
className="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
|
||||||
|
>
|
||||||
|
{!isWindowMaximized ? (
|
||||||
|
<WindowIcons.maximizeWin className="h-2 w-2" />
|
||||||
|
) : (
|
||||||
|
<WindowIcons.maximizeRestoreWin className="h-[9px] w-[9px]" />
|
||||||
|
)}
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
onClick={closeWindow}
|
||||||
|
className="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
|
||||||
|
>
|
||||||
|
<WindowIcons.closeWin className="h-2 w-2" />
|
||||||
|
</WindowButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
74
src/shared/titlebar/controls/macos.tsx
Normal file
74
src/shared/titlebar/controls/macos.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { HTMLProps, useContext, useEffect, useState } from 'react';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
import { AppWindowContext, WindowButton, WindowIcons } from '@shared/titlebar';
|
||||||
|
|
||||||
|
export function MacOS({ className, ...props }: HTMLProps<HTMLDivElement>) {
|
||||||
|
const { minimizeWindow, maximizeWindow, fullscreenWindow, closeWindow } =
|
||||||
|
useContext(AppWindowContext);
|
||||||
|
|
||||||
|
const [isAltKeyPressed, setIsAltKeyPressed] = useState(false);
|
||||||
|
const [isHovering, setIsHovering] = useState(false);
|
||||||
|
|
||||||
|
const last = isAltKeyPressed ? <WindowIcons.plusMac /> : <WindowIcons.fullMac />;
|
||||||
|
const key = 'Alt';
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
setIsHovering(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
setIsHovering(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAltKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === key) {
|
||||||
|
setIsAltKeyPressed(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAltKeyUp = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === key) {
|
||||||
|
setIsAltKeyPressed(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Attach event listeners when the component mounts
|
||||||
|
window.addEventListener('keydown', handleAltKeyDown);
|
||||||
|
window.addEventListener('keyup', handleAltKeyUp);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
'space-x-2 px-3 text-black active:text-black dark:text-black',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<WindowButton
|
||||||
|
onClick={closeWindow}
|
||||||
|
className="aspect-square h-3 w-3 cursor-default content-center items-center justify-center self-center rounded-full border border-black/[.12] bg-[#ff544d] text-center text-black/60 hover:bg-[#ff544d] active:bg-[#bf403a] active:text-black/60 dark:border-none"
|
||||||
|
>
|
||||||
|
{isHovering && <WindowIcons.closeMac />}
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
onClick={minimizeWindow}
|
||||||
|
className="aspect-square h-3 w-3 cursor-default content-center items-center justify-center self-center rounded-full border border-black/[.12] bg-[#ffbd2e] text-center text-black/60 hover:bg-[#ffbd2e] active:bg-[#bf9122] active:text-black/60 dark:border-none"
|
||||||
|
>
|
||||||
|
{isHovering && <WindowIcons.minMac />}
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
// onKeyDown={handleAltKeyDown}
|
||||||
|
// onKeyUp={handleAltKeyUp}
|
||||||
|
onClick={isAltKeyPressed ? maximizeWindow : fullscreenWindow}
|
||||||
|
className="aspect-square h-3 w-3 cursor-default content-center items-center justify-center self-center rounded-full border border-black/[.12] bg-[#28c93f] text-center text-black/60 hover:bg-[#28c93f] active:bg-[#1e9930] active:text-black/60 dark:border-none"
|
||||||
|
>
|
||||||
|
{isHovering && last}
|
||||||
|
</WindowButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
src/shared/titlebar/controls/windows.tsx
Normal file
40
src/shared/titlebar/controls/windows.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { HTMLProps, useContext } from 'react';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
import { AppWindowContext, WindowButton, WindowIcons } from '@shared/titlebar';
|
||||||
|
|
||||||
|
export function Windows({ className, ...props }: HTMLProps<HTMLDivElement>) {
|
||||||
|
const { isWindowMaximized, minimizeWindow, maximizeWindow, closeWindow } =
|
||||||
|
useContext(AppWindowContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={twMerge('h-8', className)} {...props}>
|
||||||
|
<WindowButton
|
||||||
|
onClick={minimizeWindow}
|
||||||
|
className="max-h-8 w-[46px] cursor-default rounded-none bg-transparent text-black/90 hover:bg-black/[.05] active:bg-black/[.03] dark:text-white dark:hover:bg-white/[.06] dark:active:bg-white/[.04]"
|
||||||
|
>
|
||||||
|
<WindowIcons.minimizeWin />
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
onClick={maximizeWindow}
|
||||||
|
className={twMerge(
|
||||||
|
'max-h-8 w-[46px] cursor-default rounded-none bg-transparent',
|
||||||
|
'text-black/90 hover:bg-black/[.05] active:bg-black/[.03] dark:text-white dark:hover:bg-white/[.06] dark:active:bg-white/[.04]'
|
||||||
|
// !isMaximizable && "text-white/[.36]",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{!isWindowMaximized ? (
|
||||||
|
<WindowIcons.maximizeWin />
|
||||||
|
) : (
|
||||||
|
<WindowIcons.maximizeRestoreWin />
|
||||||
|
)}
|
||||||
|
</WindowButton>
|
||||||
|
<WindowButton
|
||||||
|
onClick={closeWindow}
|
||||||
|
className="max-h-8 w-[46px] cursor-default rounded-none bg-transparent text-black/90 hover:bg-[#c42b1c] hover:text-white active:bg-[#c42b1c]/90 dark:text-white"
|
||||||
|
>
|
||||||
|
<WindowIcons.closeWin />
|
||||||
|
</WindowButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
7
src/shared/titlebar/index.ts
Normal file
7
src/shared/titlebar/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export * from './context';
|
||||||
|
export * from './components/button';
|
||||||
|
export * from './components/icons';
|
||||||
|
export * from './controls/gnome';
|
||||||
|
export * from './controls/windows';
|
||||||
|
export * from './controls/macos';
|
||||||
|
export * from './titleBar';
|
||||||
29
src/shared/titlebar/titleBar.tsx
Normal file
29
src/shared/titlebar/titleBar.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Platform } from '@tauri-apps/plugin-os';
|
||||||
|
|
||||||
|
import { AppWindowProvider, Gnome, MacOS, Windows } from '@shared/titlebar';
|
||||||
|
|
||||||
|
export function WindowTitleBar({ platform }: { platform: Platform }) {
|
||||||
|
const ControlsComponent = () => {
|
||||||
|
switch (platform) {
|
||||||
|
case 'windows':
|
||||||
|
return <Windows className="ml-auto flex" />;
|
||||||
|
case 'macos':
|
||||||
|
return <MacOS className="ml-0 flex" />;
|
||||||
|
case 'linux':
|
||||||
|
return <Gnome className="ml-auto flex" />;
|
||||||
|
default:
|
||||||
|
return <Windows className="ml-auto flex" />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppWindowProvider>
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="bg-background flex select-none flex-row overflow-hidden"
|
||||||
|
>
|
||||||
|
<ControlsComponent />
|
||||||
|
</div>
|
||||||
|
</AppWindowProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,8 +8,7 @@ import { useArk } from '@libs/ark';
|
|||||||
|
|
||||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||||
import { MemoizedArticleNote } from '@shared/notes';
|
import { MemoizedArticleNote } from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import { useArk } from '@libs/ark';
|
|||||||
|
|
||||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||||
import { MemoizedFileNote } from '@shared/notes';
|
import { MemoizedFileNote } from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
NoteSkeleton,
|
NoteSkeleton,
|
||||||
UnknownNote,
|
UnknownNote,
|
||||||
} from '@shared/notes';
|
} from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import { useArk } from '@libs/ark';
|
|||||||
|
|
||||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||||
import { MemoizedRepost, MemoizedTextNote, UnknownNote } from '@shared/notes';
|
import { MemoizedRepost, MemoizedTextNote, UnknownNote } from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ export * from './other/widgetList';
|
|||||||
export * from './other/addGroupFeeds';
|
export * from './other/addGroupFeeds';
|
||||||
export * from './other/addHashtagFeeds';
|
export * from './other/addHashtagFeeds';
|
||||||
export * from './other/userProfile';
|
export * from './other/userProfile';
|
||||||
|
export * from './titleBar';
|
||||||
|
export * from './other/nostrBandUserProfile';
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
NoteSkeleton,
|
NoteSkeleton,
|
||||||
UnknownNote,
|
UnknownNote,
|
||||||
} from '@shared/notes';
|
} from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { LiveUpdater, TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { LiveUpdater, WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { VList } from 'virtua';
|
import { VList } from 'virtua';
|
||||||
|
|
||||||
import { LoaderIcon } from '@shared/icons';
|
import { LoaderIcon } from '@shared/icons';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
import {
|
import {
|
||||||
NostrBandUserProfile,
|
NostrBandUserProfile,
|
||||||
type Profile,
|
type Profile,
|
||||||
} from '@shared/widgets/other/nostrBandUserProfile';
|
TitleBar,
|
||||||
|
WidgetWrapper,
|
||||||
|
} from '@shared/widgets';
|
||||||
|
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { VList } from 'virtua';
|
|||||||
|
|
||||||
import { LoaderIcon } from '@shared/icons';
|
import { LoaderIcon } from '@shared/icons';
|
||||||
import { MemoizedTextNote } from '@shared/notes';
|
import { MemoizedTextNote } from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import { useArk } from '@libs/ark';
|
|||||||
|
|
||||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||||
import { MemoizedNotifyNote, NoteSkeleton } from '@shared/notes';
|
import { MemoizedNotifyNote, NoteSkeleton } from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { sendNativeNotification } from '@utils/notification';
|
import { sendNativeNotification } from '@utils/notification';
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ArticleIcon, MediaIcon, PlusIcon } from '@shared/icons';
|
import { ArticleIcon, MediaIcon, PlusIcon } from '@shared/icons';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { AddGroupFeeds, AddHashtagFeeds, TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { AddGroupFeeds, AddHashtagFeeds, WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { TOPICS, WIDGET_KIND } from '@utils/constants';
|
import { TOPICS, WIDGET_KIND } from '@utils/constants';
|
||||||
import { useWidget } from '@utils/hooks/useWidget';
|
import { useWidget } from '@utils/hooks/useWidget';
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ import {
|
|||||||
NoteReplyForm,
|
NoteReplyForm,
|
||||||
} from '@shared/notes';
|
} from '@shared/notes';
|
||||||
import { ReplyList } from '@shared/notes/replies/list';
|
import { ReplyList } from '@shared/notes/replies/list';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
|
||||||
import { User } from '@shared/user';
|
import { User } from '@shared/user';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
|
|
||||||
import { useEvent } from '@utils/hooks/useEvent';
|
import { useEvent } from '@utils/hooks/useEvent';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
NoteSkeleton,
|
NoteSkeleton,
|
||||||
UnknownNote,
|
UnknownNote,
|
||||||
} from '@shared/notes';
|
} from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, WidgetWrapper } from '@shared/widgets';
|
||||||
import { WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
NoteSkeleton,
|
NoteSkeleton,
|
||||||
UnknownNote,
|
UnknownNote,
|
||||||
} from '@shared/notes';
|
} from '@shared/notes';
|
||||||
import { TitleBar } from '@shared/titleBar';
|
import { TitleBar, UserProfile, WidgetWrapper } from '@shared/widgets';
|
||||||
import { UserProfile, WidgetWrapper } from '@shared/widgets';
|
|
||||||
|
|
||||||
import { FETCH_LIMIT } from '@utils/constants';
|
import { FETCH_LIMIT } from '@utils/constants';
|
||||||
import { Widget } from '@utils/types';
|
import { Widget } from '@utils/types';
|
||||||
|
|||||||
Reference in New Issue
Block a user