Skip to content

Commit

Permalink
fix(css-editor): handle copy and paste get the plain text
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Nov 10, 2024
1 parent cda2264 commit febc678
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
53 changes: 51 additions & 2 deletions apps/renderer/src/modules/editor/css-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useLayoutEffect, useRef } from "react"
import css from "shiki/langs/css.mjs"
import githubDark from "shiki/themes/github-dark.mjs"
import githubLight from "shiki/themes/github-light.mjs"
import { useEventCallback } from "usehooks-ts"

import { shiki } from "~/components/ui/code-highlighter/shiki/shared"

Expand All @@ -19,6 +20,7 @@ export const CSSEditor: Component<{
const ref = useRef<HTMLDivElement>(null)

const isDark = useIsDark()
const updateFnRef = useRef<() => void>()
useLayoutEffect(() => {
let dispose: () => void
if (ref.current) {
Expand All @@ -32,14 +34,15 @@ export const CSSEditor: Component<{
selection?.addRange(range)

ref.current.textContent = defaultValue ?? ""
const { dispose: disposeShiki } = createPlainShiki(shiki).mount(ref.current, {
const { dispose: disposeShiki, update } = createPlainShiki(shiki).mount(ref.current, {
lang: "css",
themes: {
light: "github-light",
dark: "github-dark",
},
defaultTheme: isDark ? "dark" : "light",
})
updateFnRef.current = update
dispose = disposeShiki
}
return () => dispose?.()
Expand Down Expand Up @@ -67,6 +70,50 @@ export const CSSEditor: Component<{
})
},
})
const handleCopy = useEventCallback((e: React.ClipboardEvent<HTMLDivElement>) => {
e.preventDefault()
e.clipboardData.setData("text/plain", ref.current?.textContent ?? "")
})
const handlePaste = useEventCallback((e: React.ClipboardEvent<HTMLDivElement>) => {
e.preventDefault()
const text = e.clipboardData.getData("text/plain")

const selection = window.getSelection()
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0)
// Delete the current selection
range.deleteContents()
// Insert the text at the current cursor position
range.insertNode(document.createTextNode(text))

range.setStartAfter(range.endContainer)
range.setEndAfter(range.endContainer)
selection.removeAllRanges()
selection.addRange(range)
}
updateFnRef.current?.()
onChange(ref.current?.textContent ?? "")
// Focus the editor and set cursor to the end
if (ref.current) {
ref.current.focus()
const selection = window.getSelection()
const range = document.createRange()
range.selectNodeContents(ref.current)
range.collapse(false) // collapse to end
selection?.removeAllRanges()
selection?.addRange(range)

// Get selection position
const rect = range.getBoundingClientRect()
const containerRect = ref.current.getBoundingClientRect()
const relativeBottom = rect.bottom - containerRect.top

// If out of view, scroll to the position
if (relativeBottom > ref.current.clientHeight) {
ref.current.scrollTop += relativeBottom - ref.current.clientHeight
}
}
})
return (
<div
className={cn(
Expand All @@ -76,10 +123,12 @@ export const CSSEditor: Component<{
"focus:!bg-accent/5",
"border border-border",
"placeholder:text-theme-placeholder-text dark:bg-zinc-700/[0.15] dark:text-zinc-200",
"hover:border-accent/60",
"overflow-auto whitespace-pre hover:border-accent/60",
className,
)}
ref={ref}
onCopy={handleCopy}
onPaste={handlePaste}
contentEditable
tabIndex={0}
{...props}
Expand Down
2 changes: 2 additions & 0 deletions apps/renderer/src/modules/settings/tabs/apperance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ const CustomCSSModal = () => {
variant="outline"
onClick={(e) => {
e.preventDefault()

setUISetting("customCSS", initialCSS.current)

forceUpdate()
}}
>
Expand Down
8 changes: 4 additions & 4 deletions locales/settings/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"appearance.theme.light": "亮色",
"appearance.theme.system": "跟随系统",
"appearance.thumbnail_ratio.description": "文章列表缩略图比例",
"appearance.thumbnail_ratio.original": "原始图像",
"appearance.thumbnail_ratio.original": "原始比例",
"appearance.thumbnail_ratio.square": "正方形",
"appearance.thumbnail_ratio.title": "缩略比例",
"appearance.title": "外观",
Expand Down Expand Up @@ -155,7 +155,7 @@
"integration.instapaper.password.label": "密码",
"integration.instapaper.title": "Instapaper",
"integration.instapaper.username.label": "Instapaper 用户名",
"integration.obsidian.enable.description": "显示保存到Obsidian按钮(如果可用)",
"integration.obsidian.enable.description": "显示保存到 Obsidian 按钮(如果可用)",
"integration.obsidian.enable.label": "启用",
"integration.obsidian.title": "Obsidian",
"integration.obsidian.vaultPath.description": "你的 Obsidian 仓库的路径",
Expand Down Expand Up @@ -284,8 +284,8 @@
"wallet.ranking.rank": "排名",
"wallet.ranking.title": "Power 排名",
"wallet.rewardDescription.description1": "每日奖励基于「用户等级」和「活跃度」两部分计算",
"wallet.rewardDescription.description2": "用户等级: 由 Power 排行榜的排名决定",
"wallet.rewardDescription.description3": "用户活跃度: 使用 Follow 功能可以提升活跃度,活跃度的奖励倍数范围是 1x ~ 10x",
"wallet.rewardDescription.description2": "用户等级由 Power 排行榜的排名决定",
"wallet.rewardDescription.description3": "用户活跃度使用 Follow 功能可以提升活跃度,活跃度的奖励倍数范围是 1x ~ 10x",
"wallet.rewardDescription.level": "用户等级",
"wallet.rewardDescription.percentage": "排名比例",
"wallet.rewardDescription.reward": "奖励倍数",
Expand Down

0 comments on commit febc678

Please sign in to comment.