fix stiker on forum

This commit is contained in:
2025-04-25 17:51:30 +08:00
parent 65c69a96e5
commit a338dafc80
18 changed files with 531 additions and 316 deletions

View File

@@ -32,7 +32,7 @@ const dummyStiker = [
{
id: 7,
name: "stiker7",
url: "https://play-lh.googleusercontent.com/MHPScwJ_owQJtf26PpiANC83sGj8d_cPz_83R3XhmFN9nJUuoWHJ0Y-GaEsKhXk4sA",
url: "https://down-id.img.susercontent.com/file/39fbca466b027a644d8386f265330365",
},
{
id: 8,

View File

@@ -0,0 +1,45 @@
import { Paper, ScrollArea } from "@mantine/core";
import React from "react";
import { MainColor } from "../../color";
import { ReactQuillDynamic } from "./react_quill_dynamix";
import {
formatsReactQuill,
modulesReactQuill,
} from "./react_quill_format_for_stiker";
const ReactQuill = ReactQuillDynamic;
export function Component_V3_TextEditorWithSticker({
quillRef,
data,
onSetData,
}: {
quillRef: React.MutableRefObject<any>;
data: any;
onSetData: (value: any) => void;
}) {
return (
<>
<Paper p="sm" shadow="lg" mah={300} bg={MainColor.white}>
<ScrollArea h={280}>
<ReactQuill
forwardedRef={quillRef}
theme="snow"
value={data}
onChange={(val: any) => {
onSetData(val);
}}
modules={modulesReactQuill}
formats={formatsReactQuill}
placeholder="Ketik pesan di sini atau tambahkan stiker..."
style={{
color: "black",
backgroundColor: MainColor.white,
border: "none",
}}
/>
</ScrollArea>
</Paper>
</>
);
}

View File

@@ -0,0 +1,56 @@
import { ActionIcon, Box, Image, ScrollArea, SimpleGrid, Tooltip } from "@mantine/core";
import { IconMoodSmileFilled } from "@tabler/icons-react";
import { MainColor } from "../../color";
import { UIGlobal_Modal } from "../../ui";
import { listStiker } from "../stiker";
import { insertStickerReactQuill } from "./react_quill_format_for_stiker";
interface Props {
open: () => void;
close: () => void;
opened: boolean;
quillRef: any;
}
export const Comp_ButtonSticker = ({open, close, opened, quillRef}: Props) => {
return (
<>
<ActionIcon onClick={open} variant="transparent">
<IconMoodSmileFilled color={MainColor.white} size={30} />
</ActionIcon>
<UIGlobal_Modal
opened={opened}
close={close}
title="Pilih Stiker"
closeButton
>
<Box mah={`${400}dvh`}>
<ScrollArea h={380}>
<SimpleGrid cols={3} spacing="md">
{listStiker.map((item) => (
<Box key={item.id}>
<Tooltip label={item.name}>
<Image
src={item.url}
height={100}
width={100}
alt={item.name}
style={{ cursor: "pointer" }}
onClick={() =>
insertStickerReactQuill({
stickerUrl: item.url,
quillRef: quillRef,
close: close,
})
}
/>
</Tooltip>
</Box>
))}
</SimpleGrid>
</ScrollArea>
</Box>
</UIGlobal_Modal>
</>
);
}

View File

@@ -0,0 +1,20 @@
import { Text } from "@mantine/core";
import dynamic from "next/dynamic";
export const ReactQuillDynamic = dynamic(
async () => {
const { default: RQ } = await import("react-quill");
// Tidak perlu import CSS dengan import statement
return function comp({ forwardedRef, ...props }: any) {
return <RQ ref={forwardedRef} {...props} />;
};
},
{
ssr: false,
loading: () => (
<Text fs={"italic"} c={"gray.8"} fz={12}>
Ketik pesan di sini atau tambahkan stiker...
</Text>
),
}
);

View File

@@ -0,0 +1,61 @@
import React from "react";
export {
modulesReactQuill,
formatsReactQuill,
insertStickerReactQuill
};
const modulesReactQuill = {
toolbar: [
[{ header: [1, 2, false] }],
["bold", "italic", "underline", "strike", "blockquote"],
[{ list: "ordered" }, { list: "bullet" }],
["link"],
["clean"],
],
};
const formatsReactQuill = [
"header",
"bold",
"italic",
"underline",
"strike",
"blockquote",
"list",
"bullet",
"link",
"image",
];
const insertStickerReactQuill = ({
stickerUrl,
quillRef,
close,
}: {
stickerUrl: string;
quillRef: React.MutableRefObject<any>;
close: () => void;
}) => {
if (!quillRef.current) return;
const quill = quillRef.current.getEditor();
const range = quill.getSelection(true);
// Custom image insertion with size
// Use custom blot or HTML string with size attributes
const stickerHtml = `<img src="${stickerUrl}" alt="sticker" style="width: 40px; height: 40px;">`;
// Insert HTML at cursor position
quill.clipboard.dangerouslyPasteHTML(range.index, stickerHtml);
// Move cursor after inserted sticker
quill.setSelection(range.index + 1, 0);
// Focus back on editor
quill.focus();
// Close sticker modal
close();
};

View File

@@ -1,6 +1,14 @@
"use client";
import { Modal, Stack, Title, Group, Button, Box, ActionIcon } from "@mantine/core";
import {
Modal,
Stack,
Title,
Group,
Button,
Box,
ActionIcon,
} from "@mantine/core";
import { MainColor, AccentColor } from "../color/color_pallet";
import React from "react";
import { IconX } from "@tabler/icons-react";
@@ -12,7 +20,7 @@ export default function UIGlobal_Modal({
buttonKiri,
buttonKanan,
children,
closeButton
closeButton,
}: {
opened: any;
close: any;
@@ -20,14 +28,14 @@ export default function UIGlobal_Modal({
buttonKiri?: any;
buttonKanan?: any;
children?: React.ReactNode;
closeButton?: boolean
closeButton?: boolean;
}) {
return (
<>
<Modal
opened={opened}
onClose={() => {
close();
close();
}}
centered
withCloseButton={false}
@@ -41,16 +49,22 @@ export default function UIGlobal_Modal({
<Stack spacing={"lg"}>
<Group position="apart">
<Title order={6} color={MainColor.white} align="center">
{title}
</Title>
{closeButton ? <ActionIcon onClick={close} variant="transparent">
<IconX color="white" size={25}/>
</ActionIcon> : null}
{title}
</Title>
{closeButton ? (
<ActionIcon onClick={close} variant="transparent">
<IconX color="white" size={25} />
</ActionIcon>
) : null}
</Group>
{children ? children : <Group position="center">
<Box>{buttonKiri}</Box>
<Box>{buttonKanan}</Box>
</Group>}
{children ? (
children
) : (
<Group position="center">
<Box>{buttonKiri}</Box>
<Box>{buttonKanan}</Box>
</Group>
)}
</Stack>
</Modal>
</>