add ad
This commit is contained in:
37
package-lock.json
generated
37
package-lock.json
generated
@@ -12,6 +12,7 @@
|
|||||||
"@radix-ui/react-avatar": "^1.1.3",
|
"@radix-ui/react-avatar": "^1.1.3",
|
||||||
"@radix-ui/react-dialog": "^1.1.6",
|
"@radix-ui/react-dialog": "^1.1.6",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||||
|
"@radix-ui/react-popover": "^1.1.6",
|
||||||
"@radix-ui/react-scroll-area": "^1.2.3",
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
@@ -1619,6 +1620,42 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-popover": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.1",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.1",
|
||||||
|
"@radix-ui/react-context": "1.1.1",
|
||||||
|
"@radix-ui/react-dismissable-layer": "1.1.5",
|
||||||
|
"@radix-ui/react-focus-guards": "1.1.1",
|
||||||
|
"@radix-ui/react-focus-scope": "1.1.2",
|
||||||
|
"@radix-ui/react-id": "1.1.0",
|
||||||
|
"@radix-ui/react-popper": "1.2.2",
|
||||||
|
"@radix-ui/react-portal": "1.1.4",
|
||||||
|
"@radix-ui/react-presence": "1.1.2",
|
||||||
|
"@radix-ui/react-primitive": "2.0.2",
|
||||||
|
"@radix-ui/react-slot": "1.1.2",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||||
|
"aria-hidden": "^1.2.4",
|
||||||
|
"react-remove-scroll": "^2.6.3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-popper": {
|
"node_modules/@radix-ui/react-popper": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"@radix-ui/react-avatar": "^1.1.3",
|
"@radix-ui/react-avatar": "^1.1.3",
|
||||||
"@radix-ui/react-dialog": "^1.1.6",
|
"@radix-ui/react-dialog": "^1.1.6",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||||
|
"@radix-ui/react-popover": "^1.1.6",
|
||||||
"@radix-ui/react-scroll-area": "^1.2.3",
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||||
"@radix-ui/react-separator": "^1.1.2",
|
"@radix-ui/react-separator": "^1.1.2",
|
||||||
"@radix-ui/react-slot": "^1.1.2",
|
"@radix-ui/react-slot": "^1.1.2",
|
||||||
|
|||||||
128
src/components/AdSection.tsx
Normal file
128
src/components/AdSection.tsx
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { cn } from '../lib/utils';
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
|
||||||
|
interface AdSectionProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
closeAd?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdBannerProps {
|
||||||
|
show: boolean;
|
||||||
|
closeAd: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AdSection: React.FC<AdSectionProps> = ({ isOpen}) => {
|
||||||
|
return (
|
||||||
|
<div className="p-3 border-t border-border/40">
|
||||||
|
<div className={cn(
|
||||||
|
"rounded-lg p-2 text-center relative overflow-hidden min-h-[120px] flex flex-col justify-center",
|
||||||
|
"transition-all duration-200 bg-cover bg-center bg-no-repeat",
|
||||||
|
isOpen ? "block" : "hidden"
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
backgroundImage: "url('https://files.monica.cn/assets/botgroup/background.png')",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="absolute top-0 left-0 bg-gray-300/40 text-gray-400 text-[10px] px-1.5 py-0.5 rounded">
|
||||||
|
广告
|
||||||
|
</div>
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div className="flex flex-col items-center gap-2">
|
||||||
|
<div className="flex items-center justify-center px-6">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/monica.png"/>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm font-medium text-center text-gray-400">万能的助手, 懂你的伙伴</div>
|
||||||
|
<div className="text-[10px] font-medium text-center text-gray-400 flex items-center justify-center gap-1">由 <img src="https://files.monica.cn/assets/botgroup/deepseek.png" className="inline-block w-16"/> 驱动</div>
|
||||||
|
<div className="flex flex-col items-center justify-center gap-2 mt-3">
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<button className="p-2 bg-white rounded-full text-xs font-medium text-blue-500 font-bold hover:bg-gray-50 transition-colors shadow-sm flex items-center gap-1 group">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/wechat.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
在微信中使用
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/arrow-up.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
</button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-40 p-0" side="top" align="center" sideOffset={5} onPointerDownOutside={(e) => e.preventDefault()}>
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<img
|
||||||
|
src="https://assets.monica.cn/home-web/_next/static/media/wechatQrcode.29848e06.png"
|
||||||
|
alt="公众号二维码"
|
||||||
|
className="w-40 h-40"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
<button onClick={() => {
|
||||||
|
window.open('https://monica.cn/home/chat/Monica/monica', '_blank');
|
||||||
|
}} className="p-2 bg-white rounded-full text-xs font-medium text-blue-500 font-bold hover:bg-gray-50 transition-colors shadow-sm flex items-center gap-1">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/computer.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
在网页中对话
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/arrow-up.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const AdBanner: React.FC<AdBannerProps> = ({ show, closeAd }) => {
|
||||||
|
if (!show) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg text-center relative overflow-hidden py-2 pl-1 h-8 mr-2 flex flex-col justify-center transition-all duration-200 bg-cover bg-center bg-no-repeat"
|
||||||
|
style={{
|
||||||
|
backgroundImage: "url('https://files.monica.cn/assets/botgroup/banner-background.png')"
|
||||||
|
}}>
|
||||||
|
<div className="absolute top-0 left-0 bg-gray-300/40 text-gray-400 text-[8px] px-1 py-1.5 rounded">
|
||||||
|
广<br/>告
|
||||||
|
</div>
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div className="flex items-center gap-0 justify-center">
|
||||||
|
<div className="flex items-center justify-center w-20 pl-2">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/monica.png"/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-center gap-3 px-2">
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<button className="p-1 bg-white rounded-full text-xs font-medium text-blue-500 font-bold hover:bg-gray-50 transition-colors shadow-sm flex items-center gap-1 group">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/wechat.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
在微信中使用
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/arrow-up.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
</button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-40 p-0" side="top" align="center" sideOffset={5} onPointerDownOutside={(e) => e.preventDefault()}>
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<img
|
||||||
|
src="https://assets.monica.cn/home-web/_next/static/media/wechatQrcode.29848e06.png"
|
||||||
|
alt="公众号二维码"
|
||||||
|
className="w-40 h-40"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
<button onClick={() => {
|
||||||
|
window.open('https://monica.cn/home/chat/Monica/monica', '_blank');
|
||||||
|
}} className="p-1 bg-white rounded-full text-xs font-medium text-blue-500 font-bold hover:bg-gray-50 transition-colors shadow-sm flex items-center gap-1">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/computer.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
在网页中使用
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/arrow-up.png" className="w-4 h-4" alt="WeChat" />
|
||||||
|
</button>
|
||||||
|
<button onClick={closeAd} className="flex items-center">
|
||||||
|
<img src="https://files.monica.cn/assets/botgroup/banner-delete.png" className="w-4 h-4" alt="Delete" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { AdSection, AdBanner };
|
||||||
@@ -4,6 +4,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
@@ -21,7 +22,7 @@ import rehypeKatex from 'rehype-katex'
|
|||||||
import { SharePoster } from '@/components/SharePoster';
|
import { SharePoster } from '@/components/SharePoster';
|
||||||
import { MembersManagement } from '@/components/MembersManagement';
|
import { MembersManagement } from '@/components/MembersManagement';
|
||||||
import Sidebar from './Sidebar';
|
import Sidebar from './Sidebar';
|
||||||
|
import { AdBanner } from './AdSection';
|
||||||
// 使用本地头像数据,避免外部依赖
|
// 使用本地头像数据,避免外部依赖
|
||||||
const getAvatarData = (name: string) => {
|
const getAvatarData = (name: string) => {
|
||||||
const colors = ['#1abc9c', '#3498db', '#9b59b6', '#f1c40f', '#e67e22'];
|
const colors = ['#1abc9c', '#3498db', '#9b59b6', '#f1c40f', '#e67e22'];
|
||||||
@@ -157,6 +158,7 @@ const ChatUI = () => {
|
|||||||
const [messages, setMessages] = useState([
|
const [messages, setMessages] = useState([
|
||||||
|
|
||||||
]);
|
]);
|
||||||
|
const [showAd, setShowAd] = useState(true);
|
||||||
const [inputMessage, setInputMessage] = useState("");
|
const [inputMessage, setInputMessage] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [pendingContent, setPendingContent] = useState("");
|
const [pendingContent, setPendingContent] = useState("");
|
||||||
@@ -444,9 +446,14 @@ const ChatUI = () => {
|
|||||||
|
|
||||||
<h1 className="font-medium text-base -ml-1">{group.name}({users.length})</h1>
|
<h1 className="font-medium text-base -ml-1">{group.name}({users.length})</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* 右侧头像组和按钮 */}
|
{/* 右侧头像组和按钮 */}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
{/* 广告位 手机端不展示*/}
|
||||||
|
<div className="hidden md:block">
|
||||||
|
<AdBanner show={showAd} closeAd={() => setShowAd(false)} />
|
||||||
|
</div>
|
||||||
<div className="flex -space-x-2 ">
|
<div className="flex -space-x-2 ">
|
||||||
{users.slice(0, 4).map((user) => {
|
{users.slice(0, 4).map((user) => {
|
||||||
const avatarData = getAvatarData(user.name);
|
const avatarData = getAvatarData(user.name);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { cn } from "@/lib/utils";
|
|||||||
import GitHubButton from 'react-github-btn';
|
import GitHubButton from 'react-github-btn';
|
||||||
import '@fontsource/audiowide';
|
import '@fontsource/audiowide';
|
||||||
import { groups } from "@/config/groups";
|
import { groups } from "@/config/groups";
|
||||||
|
import { AdSection } from './AdSection';
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
@@ -118,8 +119,11 @@ const Sidebar = ({ isOpen, toggleSidebar, selectedGroupIndex = 0, onSelectGroup
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 广告位 */}
|
||||||
|
<AdSection isOpen={isOpen} />
|
||||||
|
|
||||||
{/* GitHub Star Button - 只在侧边栏打开时显示,放在底部 */}
|
{/* GitHub Star Button - 只在侧边栏打开时显示,放在底部 */}
|
||||||
<div className="p-3 mt-auto">
|
<div className="px-3 py-2 mt-auto">
|
||||||
{/* 标题移至底部 */}
|
{/* 标题移至底部 */}
|
||||||
<div className="flex items-center justify-left mb-3">
|
<div className="flex items-center justify-left mb-3">
|
||||||
<a href="/" className="flex items-center">
|
<a href="/" className="flex items-center">
|
||||||
|
|||||||
29
src/components/ui/popover.tsx
Normal file
29
src/components/ui/popover.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Popover = PopoverPrimitive.Root
|
||||||
|
|
||||||
|
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||||
|
|
||||||
|
const PopoverContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||||
|
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||||
|
<PopoverPrimitive.Portal>
|
||||||
|
<PopoverPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
align={align}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</PopoverPrimitive.Portal>
|
||||||
|
))
|
||||||
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Popover, PopoverTrigger, PopoverContent }
|
||||||
Reference in New Issue
Block a user