chore(header): beautify info card
This commit is contained in:
parent
064bbd3dec
commit
ac2323ea0b
8 changed files with 43 additions and 43 deletions
|
@ -5,7 +5,7 @@
|
||||||
"tsx": true,
|
"tsx": true,
|
||||||
"tailwind": {
|
"tailwind": {
|
||||||
"config": "tailwind.config.ts",
|
"config": "tailwind.config.ts",
|
||||||
"css": "@/assets/style.css",
|
"css": "@/assets/styles.tailwind.css",
|
||||||
"baseColor": "slate",
|
"baseColor": "slate",
|
||||||
"cssVariables": true
|
"cssVariables": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,11 +6,11 @@ import { RemeshLogger } from 'remesh-logger'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import StorageImpl from '@/impl/Storage'
|
import StorageImpl from '@/impl/Storage'
|
||||||
|
|
||||||
import './style.css'
|
import '@/assets/styles/tailwind.css'
|
||||||
|
|
||||||
export default defineContentScript({
|
export default defineContentScript({
|
||||||
cssInjectionMode: 'ui',
|
cssInjectionMode: 'ui',
|
||||||
matches: ['*://*.example.com/*'],
|
matches: ['*://*.example.com/*', '*://*.google.com/*', '*://*.v2ex.com/*'],
|
||||||
async main(ctx) {
|
async main(ctx) {
|
||||||
const store = Remesh.store({
|
const store = Remesh.store({
|
||||||
externs: [StorageImpl],
|
externs: [StorageImpl],
|
||||||
|
|
|
@ -7,7 +7,7 @@ export interface AppButtonProps {
|
||||||
|
|
||||||
const AppButton: FC<AppButtonProps> = ({ children }) => {
|
const AppButton: FC<AppButtonProps> = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<Button className="fixed bottom-5 right-5 z-top h-10 w-10 select-none rounded-full bg-yellow-400 text-xs">
|
<Button className="fixed bottom-5 right-5 z-top h-10 w-10 select-none rounded-full bg-blue-400 text-xs">
|
||||||
{children}
|
{children}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { type FC } from 'react'
|
import { type FC } from 'react'
|
||||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/HoverCard'
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/HoverCard'
|
||||||
import { Button } from '@/components/ui/Button'
|
import { Button } from '@/components/ui/Button'
|
||||||
import getWebSiteInfo from '@/utils/getWebsiteInfo'
|
import { getWebSiteInfo } from '@/utils'
|
||||||
|
|
||||||
const Header: FC = () => {
|
const Header: FC = () => {
|
||||||
const websiteInfo = getWebSiteInfo()
|
const websiteInfo = getWebSiteInfo()
|
||||||
|
@ -18,9 +18,11 @@ const Header: FC = () => {
|
||||||
<HoverCardContent className="w-80">
|
<HoverCardContent className="w-80">
|
||||||
<div className="grid grid-cols-[auto_1fr] gap-x-4">
|
<div className="grid grid-cols-[auto_1fr] gap-x-4">
|
||||||
<img className="h-14 w-14 overflow-hidden rounded-full" src={websiteInfo.icon} />
|
<img className="h-14 w-14 overflow-hidden rounded-full" src={websiteInfo.icon} />
|
||||||
<div className="grid">
|
<div className="grid items-center">
|
||||||
<h4 className="text-sm font-semibold">{websiteInfo.title}</h4>
|
<h4 className="truncate text-sm font-semibold">{websiteInfo.title}</h4>
|
||||||
<p className="text-xs text-slate-500">{websiteInfo.description}</p>
|
{websiteInfo.description && (
|
||||||
|
<p className="line-clamp-2 h-8 text-xs text-slate-500">{websiteInfo.description}</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</HoverCardContent>
|
</HoverCardContent>
|
||||||
|
|
|
@ -16,7 +16,6 @@ const Main: FC = () => {
|
||||||
const lastMessageRef = messageListRef.current?.querySelector('[data-index]:last-child')
|
const lastMessageRef = messageListRef.current?.querySelector('[data-index]:last-child')
|
||||||
const timerId = setTimeout(() => {
|
const timerId = setTimeout(() => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
console.log(isUpdate.current)
|
|
||||||
lastMessageRef?.scrollIntoView({ behavior: isUpdate.current ? 'smooth' : 'instant', block: 'end' })
|
lastMessageRef?.scrollIntoView({ behavior: isUpdate.current ? 'smooth' : 'instant', block: 'end' })
|
||||||
isUpdate.current = true
|
isUpdate.current = true
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
export interface WebSiteInfo {
|
|
||||||
host: string
|
|
||||||
hostname: string
|
|
||||||
href: string
|
|
||||||
origin: string
|
|
||||||
title: string
|
|
||||||
icon: string
|
|
||||||
description: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const getWebSiteInfo = (): WebSiteInfo => {
|
|
||||||
return {
|
|
||||||
host: document.location.host,
|
|
||||||
hostname: document.location.hostname,
|
|
||||||
href: document.location.href,
|
|
||||||
origin: document.location.origin,
|
|
||||||
title:
|
|
||||||
document.querySelector('meta[rel="og:title i"]')?.getAttribute('content') ??
|
|
||||||
document.querySelector('meta[rel="og:title i"]')?.getAttribute('content') ??
|
|
||||||
document.querySelector('meta[rel="og:site_name i"]')?.getAttribute('content') ??
|
|
||||||
document.title,
|
|
||||||
icon:
|
|
||||||
document.querySelector('meta[property="og:image" i]')?.getAttribute('href') ??
|
|
||||||
document.querySelector('link[rel="icon" i]')?.getAttribute('href') ??
|
|
||||||
document.querySelector('link[rel="shortcut icon" i]')?.getAttribute('href') ??
|
|
||||||
`${document.location.origin}/favicon.ico}`,
|
|
||||||
description:
|
|
||||||
document.querySelector('meta[property="og:description i"]')?.getAttribute('content') ??
|
|
||||||
document.querySelector('meta[name="description" i]')?.getAttribute('content') ??
|
|
||||||
''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getWebSiteInfo
|
|
|
@ -1,6 +1,16 @@
|
||||||
import { type ClassValue, clsx } from 'clsx'
|
import { type ClassValue, clsx } from 'clsx'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
|
export interface WebSiteInfo {
|
||||||
|
host: string
|
||||||
|
hostname: string
|
||||||
|
href: string
|
||||||
|
origin: string
|
||||||
|
title: string
|
||||||
|
icon: string
|
||||||
|
description: string
|
||||||
|
}
|
||||||
|
|
||||||
export const cn = (...inputs: ClassValue[]) => {
|
export const cn = (...inputs: ClassValue[]) => {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
|
@ -11,3 +21,26 @@ export const createElement = <T extends Element>(template: string) => {
|
||||||
|
|
||||||
export const chunk = <T = any>(array: T[], size: number) =>
|
export const chunk = <T = any>(array: T[], size: number) =>
|
||||||
Array.from({ length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size))
|
Array.from({ length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size))
|
||||||
|
|
||||||
|
export const getWebSiteInfo = (): WebSiteInfo => {
|
||||||
|
return {
|
||||||
|
host: document.location.host,
|
||||||
|
hostname: document.location.hostname,
|
||||||
|
href: document.location.href,
|
||||||
|
origin: document.location.origin,
|
||||||
|
title:
|
||||||
|
document.querySelector('meta[rel="og:title i"]')?.getAttribute('content') ??
|
||||||
|
document.querySelector('meta[rel="og:title i"]')?.getAttribute('content') ??
|
||||||
|
document.querySelector('meta[rel="og:site_name i"]')?.getAttribute('content') ??
|
||||||
|
document.title,
|
||||||
|
icon:
|
||||||
|
document.querySelector('meta[property="og:image" i]')?.getAttribute('href') ??
|
||||||
|
document.querySelector('link[rel="icon" i]')?.getAttribute('href') ??
|
||||||
|
document.querySelector('link[rel="shortcut icon" i]')?.getAttribute('href') ??
|
||||||
|
`${document.location.origin}/favicon.ico`,
|
||||||
|
description:
|
||||||
|
document.querySelector('meta[property="og:description i"]')?.getAttribute('content') ??
|
||||||
|
document.querySelector('meta[name="description" i]')?.getAttribute('content') ??
|
||||||
|
''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue