feat: i18n in widget
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" stroke="#101828" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 241 B |
+4
-2
@@ -8,6 +8,7 @@ import auth from "../public/locales/en/auth.json";
|
||||
import member from "../public/locales/en/member.json";
|
||||
import chat from "../public/locales/en/chat.json";
|
||||
import fav from "../public/locales/en/fav.json";
|
||||
import widget from "../public/locales/en/widget.json";
|
||||
import welcome from "../public/locales/en/welcome.json";
|
||||
import setting from "../public/locales/en/setting.json";
|
||||
import file from "../public/locales/en/file.json";
|
||||
@@ -26,7 +27,8 @@ export const resources = {
|
||||
member,
|
||||
welcome,
|
||||
setting,
|
||||
file
|
||||
file,
|
||||
widget
|
||||
}
|
||||
} as const;
|
||||
i18n.on("languageChanged", (lng) => {
|
||||
@@ -46,7 +48,7 @@ i18n
|
||||
// init i18next
|
||||
// for all options read: https://www.i18next.com/overview/configuration-options
|
||||
.init<HttpBackendOptions>({
|
||||
ns: ["common", "chat", "member", "setting", "fav", "file", "welcome", "auth"],
|
||||
ns: ["common", "chat", "member", "setting", "fav", "file", "welcome", "auth", "widget"],
|
||||
defaultNS,
|
||||
load: "languageOnly",
|
||||
// lng: "jp",
|
||||
|
||||
@@ -6,7 +6,9 @@ type Props = {
|
||||
|
||||
const Index: FC<Props> = () => {
|
||||
return (
|
||||
<footer className="text-xs text-gray-300 text-center pb-2">Host your own <a href="https://voce.chat" target="_blank" rel="noopener noreferrer" className="text-gray-400">voce.chat</a></footer>
|
||||
<footer className="text-xs text-gray-300 text-center pb-2">
|
||||
Host your own <a href="https://voce.chat" target="_blank" rel="noopener noreferrer" className="text-gray-400">voce.chat</a>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ const Index: FC<Props> = ({ handleClose }) => {
|
||||
return (
|
||||
<header className="relative flex justify-between items-center h-14 px-4 py-2" style={{ backgroundColor: color }}>
|
||||
<div className="relative w-8 h-8">
|
||||
<img src={logo} alt="logo" className="w-full h-full rounded-full" />
|
||||
{logo && <img src={logo} alt="logo" className="w-full h-full rounded-full" />}
|
||||
</div>
|
||||
<div className="flex-1 px-4 pr-2 text-lg">
|
||||
<span className="text-lg font-bold truncate text-gray-50" style={{ color: fgColor }}>{name}</span>
|
||||
|
||||
@@ -14,10 +14,12 @@ import Input from '../../../common/component/styled/Input';
|
||||
import useGithubAuthConfig from '../../../common/hook/useGithubAuthConfig';
|
||||
import useGoogleAuthConfig from '../../../common/hook/useGoogleAuthConfig';
|
||||
import { useWidget } from '../../WidgetContext';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
// type Props = {}
|
||||
|
||||
const Login = () => {
|
||||
const { t } = useTranslation("widget");
|
||||
const dispatch = useDispatch();
|
||||
const { color, fgColor, from } = useWidget();
|
||||
const { clientId } = useGoogleAuthConfig();
|
||||
@@ -72,10 +74,12 @@ const Login = () => {
|
||||
return (
|
||||
<div className="w-full max-w-[288px] flex flex-col gap-2 mt-4 animate-[fadeInUp_.5s_.8s_ease-in-out_both]">
|
||||
<div className="bg-white dark:bg-gray-700 border dark:border-gray-500 rounded-lg">
|
||||
<form className="px-4 py-3 flex flex-col gap-2" onSubmit={handleSubmit}>
|
||||
<Input required placeholder="Name" name='username' />
|
||||
<form className="px-4 py-3 flex flex-col gap-2" onSubmit={handleSubmit} >
|
||||
<Input required placeholder="Name" type='text' name='username' />
|
||||
{/* <Input required placeholder="Email" type="email" name='email' /> */}
|
||||
<StyledButton disabled={isLoading} type="submit" className={clsx("small", `bg-[${color}] text-[${fgColor}]`)}>Start Chat</StyledButton>
|
||||
<StyledButton disabled={isLoading} type="submit" className={clsx("small", `bg-[${color}] text-[${fgColor}]`)}>
|
||||
{t("start_chat")}
|
||||
</StyledButton>
|
||||
{hasSocialLogins && <Divider content='OR' />}
|
||||
{googleLogin && <GoogleLoginButton clientId={clientId} />}
|
||||
{enableGithubLogin && <GithubLoginButton client_id={githubAuthConfig?.client_id} source="widget" />}
|
||||
|
||||
@@ -33,9 +33,10 @@ const Index = (props: IWidgetMessage) => {
|
||||
break;
|
||||
}
|
||||
return <div className={clsx('group flex mb-3', host ? 'relative justify-start items-start' : 'items-center justify-end px-3')}>
|
||||
{host ? <><div className="w-9 h-9 absolute top-0 left-3">
|
||||
<img src={logo} alt="avatar" className='rounded-full w-9 h-9' />
|
||||
</div>
|
||||
{host ? <>
|
||||
<div className="w-9 h-9 absolute top-0 left-3">
|
||||
<img src={logo} alt="avatar" className='rounded-full w-9 h-9' />
|
||||
</div>
|
||||
<div className="pl-14 flex items-center">
|
||||
{contentContainer}
|
||||
<Time time={create_time} />
|
||||
|
||||
@@ -2,6 +2,8 @@ import { useRef, useState, memo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import useSendMessage from '../../common/hook/useSendMessage';
|
||||
import { useWidget } from '../WidgetContext';
|
||||
import IconSend from '../../assets/icons/send.svg';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +13,7 @@ type Props = {
|
||||
}
|
||||
let isComposing = false;
|
||||
const MessageInput = (props: Props) => {
|
||||
const { t } = useTranslation("widget");
|
||||
const { color } = useWidget();
|
||||
const { from, to } = props;
|
||||
const { sendMessage } = useSendMessage({
|
||||
@@ -27,16 +30,23 @@ const MessageInput = (props: Props) => {
|
||||
`ring-1 ring-gray-200 dark:ring-gray-800 focus:ring-2 focus:ring-[${color}]`,
|
||||
'focus:outline-none',
|
||||
);
|
||||
const handleSend = () => {
|
||||
sendMessage({
|
||||
type: "text",
|
||||
content
|
||||
});
|
||||
setContent("");
|
||||
};
|
||||
return (
|
||||
<div className="relative border-t border-gray-300 dark:border-gray-600 w-full">
|
||||
<div className={'px-3 py-2 min-h-[48px]'}>
|
||||
<div className={'px-3 py-2 min-h-[48px] flex items-center gap-2'}>
|
||||
<textarea
|
||||
// disabled={isSending}
|
||||
ref={ref}
|
||||
maxLength={4096}
|
||||
className={textareaClassName}
|
||||
value={content}
|
||||
placeholder="Type and press enter"
|
||||
placeholder={t("placeholder_send")}
|
||||
onChange={e => setContent(e.target.value)}
|
||||
onCompositionStart={() => {
|
||||
isComposing = true;
|
||||
@@ -56,14 +66,13 @@ const MessageInput = (props: Props) => {
|
||||
// e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (content.trim().length === 0) return;
|
||||
sendMessage({
|
||||
type: "text",
|
||||
content
|
||||
});
|
||||
setContent("");
|
||||
handleSend();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button onClick={handleSend} disabled={content.trim().length === 0} className='px-2 py-1 disabled:opacity-60'>
|
||||
<IconSend className="dark:stroke-white w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -2,25 +2,28 @@
|
||||
import { memo } from 'react';
|
||||
import { useAppSelector } from '../../app/store';
|
||||
import Login from './Login';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Props = {
|
||||
needLogin?: boolean
|
||||
}
|
||||
const Index = ({ needLogin = false }: Props) => {
|
||||
const { logo } = useAppSelector(store => store.server);
|
||||
const { t } = useTranslation("widget");
|
||||
// console.log("logooo", logo);
|
||||
return (
|
||||
<>
|
||||
<div className="group relative flex justify-start items-start mb-3">
|
||||
<div className="w-9 h-9 absolute top-0 left-3">
|
||||
<img src={logo} alt="logo" className="rounded-full bg-transparent w-9 h-9" />
|
||||
{logo && <img src={logo} alt="logo" className="rounded-full bg-transparent w-9 h-9" />}
|
||||
</div>
|
||||
<div className="pl-14">
|
||||
<div className="rounded-lg" style={{ maxWidth: 'min(((100vw - 56px) - 20px) - 64px, 360px)' }}>
|
||||
<div className="text-md text-gray-900 dark:text-gray-100 px-3 py-1.5 bg-gray-100 dark:bg-gray-900 rounded-lg mb-1.5">
|
||||
{needLogin ?
|
||||
`👋 Hi there, Nice to meet you! Please login before we have a nice talk 👇`
|
||||
t("welcome_not_login")
|
||||
:
|
||||
`👋 Hi there, Nice to meet you! `}
|
||||
t("welcome")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user