Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: feed claim #77

Merged
merged 12 commits into from
Jun 21, 2024
Merged
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default defineConfig(
"unicorn/consistent-function-scoping": "warn",
"unicorn/prefer-module": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-unused-expressions": 0,
},
settings: {
tailwindcss: {
Expand Down
1 change: 1 addition & 0 deletions icons/mgc/check_circle_filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions icons/mgc/check_filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions icons/mgc/copy_2_cute_re.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/main/tipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export const router = {

showContextMenu: t.procedure
.input<{
items: Array<{ type: "text", label: string } | { type: "separator" }>
items: Array<
| { type: "text", label: string, enabled?: boolean }
| { type: "separator" }
>
}>()
.action(async ({ input, context }) => {
const menu = Menu.buildFromTemplate(
Expand All @@ -29,6 +32,7 @@ export const router = {
}
return {
label: item.label,
enabled: item.enabled ?? true,
click() {
context.sender.send("menu-click", index)
},
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/src/atoms/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* eslint-disable unicorn/no-unreadable-array-destructuring */
import type { User } from "@auth/core/types"
import { createAtomHooks } from "@renderer/lib/jotai"
import { atom } from "jotai"

export const [, , useUser, useSetUser, getUser, setUser] = createAtomHooks(
atom<Nullable<User>>(null),
)
1 change: 1 addition & 0 deletions src/renderer/src/components/ui/auto-resize-height.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const AutoResizeHeight: React.FC<AnimateChangeInHeightProps> = ({
const resizeObserver = new ResizeObserver((entries) => {
// We only have one entry, so we can use entries[0].
const observedHeight = entries[0].contentRect.height
// add margin top
setHeight(observedHeight)
})

Expand Down
3 changes: 1 addition & 2 deletions src/renderer/src/components/ui/button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ export const ActionButton = React.forwardRef<
</TooltipTrigger>
<TooltipContent side={tooltipSide ?? "bottom"}>
{tooltip}
{shortcut &&
shortcut.split("+").map((key) => <Kbd key={key}>{key}</Kbd>)}
{shortcut && shortcut.split("+").map((key) => <Kbd key={key}>{key}</Kbd>)}
</TooltipContent>
</Tooltip>
</>
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/components/ui/button/variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const styledButtonVariant = cva(
{
variant: "plain",
status: "disabled",
className: "text-theme-disabled border-theme-inactive dark:border-zinc-800",
className: "text-theme-disabled border-theme-inactive dark:border-zinc-800 hover:!bg-theme-background",
},
],
variants: {
Expand Down
64 changes: 64 additions & 0 deletions src/renderer/src/components/ui/code-highlighter/copy-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { cn } from "@renderer/lib/utils"
import type { Variants } from "framer-motion"
import { AnimatePresence, m } from "framer-motion"
import { useCallback, useRef, useState } from "react"

import { MotionButtonBase } from "../button"

const copyIconVariants: Variants = {
initial: {
opacity: 1,
scale: 1,
},
animate: {
opacity: 1,
scale: 1,
},
exit: {
opacity: 0,
scale: 0,
},
}

export const CopyButton: Component<{
value: string
}> = ({ value, className }) => {
const [copied, setCopied] = useState(false)
const copiedTimerRef = useRef<any>()
const handleCopy = useCallback(() => {
navigator.clipboard.writeText(value)
setCopied(true)

clearTimeout(copiedTimerRef.current)
copiedTimerRef.current = setTimeout(() => {
setCopied(false)
}, 2000)
}, [value])
return (
<MotionButtonBase
onClick={handleCopy}
className={cn(
"center flex text-xs",
"rounded-md border border-theme-accent/5 bg-theme-accent/80 p-1.5 text-white backdrop-blur duration-200",

className,
)}
>
<AnimatePresence mode="wait">
{copied ? (
<m.i
key="copied"
className="i-mgc-check-filled size-4"
{...copyIconVariants}
/>
) : (
<m.i
key="copy"
className="i-mgc-copy-2-cute-re size-4"
{...copyIconVariants}
/>
)}
</AnimatePresence>
</MotionButtonBase>
)
}
1 change: 1 addition & 0 deletions src/renderer/src/components/ui/code-highlighter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./copy-button"
109 changes: 70 additions & 39 deletions src/renderer/src/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,26 @@ import * as TabsPrimitive from "@radix-ui/react-tabs"
import { cn } from "@renderer/lib/utils"
import type { VariantProps } from "class-variance-authority"
import { cva } from "class-variance-authority"
import { m } from "framer-motion"
import * as React from "react"

const Tabs = TabsPrimitive.Root

const tabsListVariants = cva(
"",
{
variants: {
variant: {
default: "border-b",
rounded: "rounded-md bg-muted p-1",
},
},
defaultVariants: {
variant: "default",
const tabsListVariants = cva("", {
variants: {
variant: {
default: "border-b",
rounded: "rounded-md bg-muted p-1",
},
},
)
defaultVariants: {
variant: "default",
},
})

export interface TabsListProps
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,
VariantProps<typeof tabsListVariants> {
}
VariantProps<typeof tabsListVariants> {}
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
TabsListProps
Expand All @@ -41,39 +38,73 @@ const TabsList = React.forwardRef<
))
TabsList.displayName = TabsPrimitive.List.displayName

const tabsTriggerVariants = cva(
"",
{
variants: {
variant: {
default: "py-1.5 border-b-2 border-transparent data-[state=active]:border-current data-[state=active]:text-theme-accent dark:data-[state=active]:text-theme-accent-500",
rounded: "py-1 rounded-sm data-[state=active]:bg-theme-accent-300 dark:data-[state=active]:bg-theme-accent-800 data-[state=active]:shadow-sm",
},
},
defaultVariants: {
variant: "default",
const tabsTriggerVariants = cva("", {
variants: {
variant: {
default:
"py-1.5 border-b-2 border-transparent data-[state=active]:text-theme-accent dark:data-[state=active]:text-theme-accent-500",
rounded:
"py-1 rounded-sm data-[state=active]:bg-theme-accent-300 dark:data-[state=active]:bg-theme-accent-800 data-[state=active]:shadow-sm",
},
},
)
defaultVariants: {
variant: "default",
},
})

export interface TabsTriggerProps
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,
VariantProps<typeof tabsTriggerVariants> {
}
VariantProps<typeof tabsTriggerVariants> {}
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
TabsTriggerProps
>(({ className, variant, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap px-3 text-sm font-medium ring-offset-background transition-all disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-theme-foreground",
tabsTriggerVariants({ variant }),
className,
)}
{...props}
/>
))
>(({ className, variant, children, ...props }, ref) => {
const triggerRef = React.useRef(null)
React.useImperativeHandle(ref, () => triggerRef.current!, [ref])

const [isSelect, setIsSelect] = React.useState(false)
React.useLayoutEffect(() => {
if (!triggerRef.current) return

const trigger = triggerRef.current as HTMLElement

const isSelect = trigger.dataset.state === "active"
setIsSelect(isSelect)
const ob = new MutationObserver(() => {
const isSelect = trigger.dataset.state === "active"
setIsSelect(isSelect)
})
ob.observe(trigger, {
attributes: true,
attributeFilter: ["data-state"],
})

return () => {
ob.disconnect()
}
}, [])

return (
<TabsPrimitive.Trigger
ref={triggerRef}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap px-3 text-sm font-medium ring-offset-background transition-all disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-theme-foreground",
"relative",
tabsTriggerVariants({ variant }),
className,
)}
{...props}
>
{children}
{isSelect && (
<m.span
layoutId="tab-selected-underline"
className="absolute -bottom-1 h-0.5 w-[calc(100%-16px)] rounded bg-theme-accent"
/>
)}
</TabsPrimitive.Trigger>
)
})
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName

const TabsContent = React.forwardRef<
Expand Down
Loading
Loading