add locales
This commit is contained in:
1 parent
6ac67596f5
commit
d9183b6d2c
15 files changed
+228
-90
No files matched your search
@@ -85,9 +85,9 @@ export function MailList(props: { mails: Email[] }) {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grids flex flex-col flex-1 h-[418px] overflow-y-auto p-2">
|
||||
<div className="grids flex flex-col flex-1 h-[450px] overflow-y-auto p-2">
|
||||
{data.length === 0 && (
|
||||
<div className="w-full items-center h-[418px] flex-col justify-center flex">
|
||||
<div className="w-full items-center h-[450px] flex-col justify-center flex">
|
||||
<Loader />
|
||||
<p className="text-zinc-400 mt-6">{t("Waiting for emails...")}</p>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "react";
|
||||
import Modal from "./modal";
|
||||
import { Form, useNavigation } from "@remix-run/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function SenderModal({
|
||||
senderEmail,
|
||||
@@ -18,25 +19,22 @@ export default function SenderModal({
|
||||
setShowSenderModal: Dispatch<SetStateAction<boolean>>;
|
||||
}) {
|
||||
const navigation = useNavigation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Modal showModal={showSenderModal} setShowModal={setShowSenderModal}>
|
||||
<div className="w-full overflow-hidden bg-white shadow-xl p-4 md:max-w-3xl md:rounded-2xl md:border md:border-gray-200">
|
||||
<div className="w-full overflow-hidden bg-white/95 backdrop-blur-xl shadow-xl p-4 md:max-w-3xl md:rounded-2xl md:border md:border-gray-200">
|
||||
<div className="flex flex-col items-center justify-center space-y-3 border-b border-gray-200 px-4 py-5 pt-8 text-center md:px-16">
|
||||
<h3 className="font-display text-2xl font-bold">Send email</h3>
|
||||
<p className="text-gray-500">Forward only, no storage</p>
|
||||
<p className="text-sm text-gray-500">
|
||||
⚠️Please do not send illegal content such as politics, pornography,
|
||||
etc
|
||||
</p>
|
||||
<h3 className="font-display text-2xl font-bold">Vmail Sender</h3>
|
||||
<p className="text-gray-500">{t("Forward only, no storage")}</p>
|
||||
</div>
|
||||
<Form method="POST" className="flex flex-col mt-4 space-y-4">
|
||||
<div className="w-full flex gap-4 md:flex-row px-4">
|
||||
<Form method="POST" className="flex flex-col mt-4 space-y-4 px-4">
|
||||
<div className="w-full flex flex-col gap-4 md:flex-row">
|
||||
<input
|
||||
value={senderEmail}
|
||||
type="email"
|
||||
name="senderEmail"
|
||||
placeholder="发件人邮箱*"
|
||||
placeholder={t("Sending email *")}
|
||||
required
|
||||
disabled
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
@@ -44,31 +42,29 @@ export default function SenderModal({
|
||||
<input
|
||||
type="text"
|
||||
name="senderName"
|
||||
placeholder="发件人昵称*"
|
||||
placeholder={t("Sending name")}
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col gap-4 md:flex-row">
|
||||
<input
|
||||
type="email"
|
||||
name="receiverEmail"
|
||||
placeholder={t("Recipient email *")}
|
||||
required
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="subject"
|
||||
placeholder={t("Email subject *")}
|
||||
required
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full px-4">
|
||||
<input
|
||||
type="email"
|
||||
name="receiverEmail"
|
||||
placeholder="收件人邮箱*"
|
||||
required
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full px-4">
|
||||
<input
|
||||
type="text"
|
||||
name="subject"
|
||||
placeholder="邮件主题*"
|
||||
required
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full px-4">
|
||||
<div className="w-full">
|
||||
<select
|
||||
name="type"
|
||||
className="rounded-md border border-slate-200 px-3 py-2 shadow-inner w-full">
|
||||
@@ -78,22 +74,29 @@ export default function SenderModal({
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="w-full px-4">
|
||||
<div className="w-full">
|
||||
<textarea
|
||||
name="content"
|
||||
placeholder="邮件内容*"
|
||||
placeholder={t("Email content *")}
|
||||
required
|
||||
className="h-24 p-2 border border-slate-200 shadow-inner rounded-md w-full"></textarea>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<button
|
||||
type="submit"
|
||||
value="send"
|
||||
name="_action"
|
||||
className="py-2.5 text-white rounded-md w-full bg-cyan-600 hover:opacity-90 disabled:cursor-not-allowed disabled:bg-zinc-500">
|
||||
{navigation.state === "submitting" ? "Sending..." : "Send"}
|
||||
</button>
|
||||
className="min-h-24 p-2 border border-slate-200 shadow-inner rounded-md w-full"></textarea>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
value="send"
|
||||
name="_action"
|
||||
disabled={navigation.state != "idle"}
|
||||
className="py-2.5 text-white rounded-md w-full bg-cyan-600 hover:opacity-90 disabled:cursor-not-allowed disabled:bg-zinc-500">
|
||||
{navigation.state === "submitting" ? t("Sending...") : t("Send")}
|
||||
</button>
|
||||
<p className="text-sm text-gray-500 mt-4">
|
||||
🚫
|
||||
{t(
|
||||
"Please do not send illegal content such as politics, pornography, etc"
|
||||
)}
|
||||
.
|
||||
</p>
|
||||
</Form>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -69,6 +69,7 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
((await userMailboxCookie.parse(
|
||||
request.headers.get("Cookie")
|
||||
)) as string) || undefined;
|
||||
const sendWorkerUrl = process.env.SEND_WORKER_URL || "";
|
||||
|
||||
if (_action === "stop") {
|
||||
if (IuserMailbox) {
|
||||
@@ -81,32 +82,32 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
});
|
||||
}
|
||||
} else if (_action === "create") {
|
||||
// const response = (await request.formData()).get("cf-turnstile-response");
|
||||
// if (!response) {
|
||||
// return {
|
||||
// error: "No captcha response",
|
||||
// };
|
||||
// }
|
||||
// const verifyEndpoint =
|
||||
// "https://challenges.cloudflare.com/turnstile/v0/siteverify";
|
||||
// const secret =
|
||||
// process.env.TURNSTILE_SECRET || "1x0000000000000000000000000000000AA";
|
||||
// const resp = await fetch(verifyEndpoint, {
|
||||
// method: "POST",
|
||||
// body: JSON.stringify({
|
||||
// secret,
|
||||
// response,
|
||||
// }),
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// });
|
||||
// const data = await resp.json();
|
||||
// if (!data.success) {
|
||||
// return {
|
||||
// error: "Failed to verify captcha",
|
||||
// };
|
||||
// }
|
||||
const response = (await request.formData()).get("cf-turnstile-response");
|
||||
if (!response) {
|
||||
return {
|
||||
error: "No captcha response",
|
||||
};
|
||||
}
|
||||
const verifyEndpoint =
|
||||
"https://challenges.cloudflare.com/turnstile/v0/siteverify";
|
||||
const secret =
|
||||
process.env.TURNSTILE_SECRET || "1x0000000000000000000000000000000AA";
|
||||
const resp = await fetch(verifyEndpoint, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
secret,
|
||||
response,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (!data.success) {
|
||||
return {
|
||||
error: "Failed to verify captcha",
|
||||
};
|
||||
}
|
||||
|
||||
const domain = process.env.EMAIL_DOMAIN || "";
|
||||
if (!domain) {
|
||||
@@ -122,8 +123,8 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
"Set-Cookie": userMailbox,
|
||||
},
|
||||
});
|
||||
} else if (_action === "send") {
|
||||
const res = await fetch(process.env.SEND_WORKER_URL || "", {
|
||||
} else if (_action === "send" && sendWorkerUrl) {
|
||||
const res = await fetch(sendWorkerUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -131,7 +132,7 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
body: JSON.stringify({
|
||||
from: {
|
||||
email: IuserMailbox,
|
||||
name: formData.get("senderName") as string,
|
||||
name: formData.get("senderName") || "Anonymous",
|
||||
},
|
||||
personalizations: [
|
||||
{
|
||||
@@ -152,9 +153,12 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
],
|
||||
}),
|
||||
});
|
||||
console.log("[res]", res);
|
||||
|
||||
return redirect("/", {});
|
||||
console.log("[res]", res.status);
|
||||
return redirect("/");
|
||||
} else {
|
||||
return {
|
||||
error: "Invalid action",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -215,6 +219,15 @@ export default function Index() {
|
||||
className="py-2.5 rounded-md w-full bg-cyan-600 hover:opacity-90 disabled:cursor-not-allowed disabled:bg-zinc-500">
|
||||
{t("Stop")}
|
||||
</button>
|
||||
|
||||
<div className="text-sm text-gray-300 mt-4">
|
||||
{t("Vmail sender is beta now. ")}
|
||||
<span
|
||||
onClick={() => setShowSenderModal(true)}
|
||||
className="text-cyan-500 cursor-pointer">
|
||||
{t("Try it")}.
|
||||
</span>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
@@ -240,6 +253,9 @@ export default function Index() {
|
||||
className="py-2.5 rounded-md w-full bg-cyan-600 hover:opacity-90 disabled:cursor-not-allowed disabled:bg-zinc-500">
|
||||
{t("Create temporary email")}
|
||||
</button>
|
||||
<p className="mt-4 text-sm text-gray-300">
|
||||
Vmail can now send emails!
|
||||
</p>
|
||||
</Form>
|
||||
)}
|
||||
<div>
|
||||
@@ -247,8 +263,6 @@ export default function Index() {
|
||||
<div className="text-red-500">{t(actionData.error)}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button onClick={() => setShowSenderModal(true)}>出来</button>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex-1 overflow-hidden">
|
||||
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "Über",
|
||||
"Privacy": "Datenschutz",
|
||||
"INBOX": "POSTEINGANG",
|
||||
"Waiting for emails...": "Warte auf E-Mails..."
|
||||
"Waiting for emails...": "Warte auf E-Mails...",
|
||||
"Try it": "Ausprobieren",
|
||||
"Forward only, no storage": "Nur weiterleiten, keine Speicherung",
|
||||
"Sending email *": "E-Mail senden *",
|
||||
"Sending name": "Senden von Name",
|
||||
"Recipient email *": "Empfänger-E-Mail *",
|
||||
"Email subject *": "E-Mail-Betreff *",
|
||||
"Email content *": "E-Mail-Inhalt *",
|
||||
"Sending...": "Senden...",
|
||||
"Send": "Senden",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Bitte senden Sie keine illegalen Inhalte wie Politik, Pornografie, usw."
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "About",
|
||||
"Privacy": "Privacy",
|
||||
"INBOX": "INBOX",
|
||||
"Waiting for emails...": "Waiting for emails..."
|
||||
"Waiting for emails...": "Waiting for emails...",
|
||||
"Try it": "Try it",
|
||||
"Forward only, no storage": "Forward only, no storage",
|
||||
"Sending email *": "Sending email *",
|
||||
"Sending name": "Sending name",
|
||||
"Recipient email *": "Recipient email *",
|
||||
"Email subject *": "Email subject *",
|
||||
"Email content *": "Email content *",
|
||||
"Sending...": "Sending...",
|
||||
"Send": "Send",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Please do not send illegal content such as politics, pornography, etc"
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "À propos",
|
||||
"Privacy": "Vie privée",
|
||||
"INBOX": "BOÎTE DE RECEPTION",
|
||||
"Waiting for emails...": "En attente de courriels..."
|
||||
"Waiting for emails...": "En attente de courriels...",
|
||||
"Try it": "Essayer",
|
||||
"Forward only, no storage": "Transférer uniquement, pas de stockage",
|
||||
"Sending email *": "Envoyer un email *",
|
||||
"Sending name": "Nom d'envoi",
|
||||
"Recipient email *": "Email du destinataire *",
|
||||
"Email subject *": "Objet de l'email *",
|
||||
"Email content *": "Contenu de l'email *",
|
||||
"Sending...": "Envoi en cours...",
|
||||
"Send": "Envoyer",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Veuillez ne pas envoyer de contenu illégal tel que de la politique, de la pornographie, etc."
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "के बारे में",
|
||||
"Privacy": "गोपनीयता",
|
||||
"INBOX": "इनबॉक्स",
|
||||
"Waiting for emails...": "ईमेल की प्रतीक्षा कर रहा है..."
|
||||
"Waiting for emails...": "ईमेल की प्रतीक्षा कर रहा है...",
|
||||
"Try it": "इसे प्रयास करें",
|
||||
"Forward only, no storage": "केवल आगे भेजें, कोई संग्रहण नहीं",
|
||||
"Sending email *": "ईमेल भेजना *",
|
||||
"Sending name": "भेजने वाले का नाम",
|
||||
"Recipient email *": "प्राप्तकर्ता ईमेल *",
|
||||
"Email subject *": "ईमेल विषय *",
|
||||
"Email content *": "ईमेल की सामग्री *",
|
||||
"Sending...": "भेज रहा है...",
|
||||
"Send": "भेजें",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "कृपया राजनीति, अश्लीलता आदि जैसी अवैध सामग्री न भेजें"
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "Informazioni",
|
||||
"Privacy": "Privacy",
|
||||
"INBOX": "INBOX",
|
||||
"Waiting for emails...": "In attesa di email..."
|
||||
"Waiting for emails...": "In attesa di email...",
|
||||
"Try it": "Provalo",
|
||||
"Forward only, no storage": "Solo inoltra, nessuna archiviazione",
|
||||
"Sending email *": "Invio email *",
|
||||
"Sending name": "Nome invio",
|
||||
"Recipient email *": "Email del destinatario *",
|
||||
"Email subject *": "Oggetto dell'email *",
|
||||
"Email content *": "Contenuto dell'email *",
|
||||
"Sending...": "Inviando...",
|
||||
"Send": "Invia",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Si prega di non inviare contenuti illegali come politica, pornografia, ecc."
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "について",
|
||||
"Privacy": "プライバシー",
|
||||
"INBOX": "インボックス",
|
||||
"Waiting for emails...": "メールを待っています..."
|
||||
"Waiting for emails...": "メールを待っています...",
|
||||
"Try it": "試してみる",
|
||||
"Forward only, no storage": "転送のみ、保存なし",
|
||||
"Sending email *": "メールの送信 *",
|
||||
"Sending name": "送信者名",
|
||||
"Recipient email *": "受信者のメールアドレス *",
|
||||
"Email subject *": "メールの件名 *",
|
||||
"Email content *": "メールの内容 *",
|
||||
"Sending...": "送信中...",
|
||||
"Send": "送信",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "政治、ポルノなどの違法なコンテンツを送信しないでください"
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "소개",
|
||||
"Privacy": "개인정보",
|
||||
"INBOX": "인박스",
|
||||
"Waiting for emails...": "이메일 기다리는 중..."
|
||||
"Waiting for emails...": "이메일 기다리는 중...",
|
||||
"Try it": "시도해 보세요",
|
||||
"Forward only, no storage": "전달만, 저장 없음",
|
||||
"Sending email *": "이메일 보내기 *",
|
||||
"Sending name": "보내는 이름",
|
||||
"Recipient email *": "수신자 이메일 *",
|
||||
"Email subject *": "이메일 제목 *",
|
||||
"Email content *": "이메일 내용 *",
|
||||
"Sending...": "전송 중...",
|
||||
"Send": "보내기",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "정치, 음란물 등과 같은 불법 콘텐츠를 보내지 마십시오"
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "Sobre",
|
||||
"Privacy": "Privacidade",
|
||||
"INBOX": "CAIXA DE ENTRADA",
|
||||
"Waiting for emails...": "Aguardando e-mails..."
|
||||
"Waiting for emails...": "Aguardando e-mails...",
|
||||
"Try it": "Experimente",
|
||||
"Forward only, no storage": "Apenas encaminhar, sem armazenamento",
|
||||
"Sending email *": "Enviar e-mail *",
|
||||
"Sending name": "Nome do remetente",
|
||||
"Recipient email *": "Email do destinatário *",
|
||||
"Email subject *": "Assunto do email *",
|
||||
"Email content *": "Conteúdo do email *",
|
||||
"Sending...": "Enviando...",
|
||||
"Send": "Enviar",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Por favor, não envie conteúdo ilegal como política, pornografia, etc."
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "О нас",
|
||||
"Privacy": "Конфиденциальность",
|
||||
"INBOX": "ВХОДЯЩИЕ",
|
||||
"Waiting for emails...": "Ожидание писем..."
|
||||
"Waiting for emails...": "Ожидание писем...",
|
||||
"Try it": "Попробуйте",
|
||||
"Forward only, no storage": "Только пересылка, без сохранения",
|
||||
"Sending email *": "Отправка электронной почты *",
|
||||
"Sending name": "Имя отправителя",
|
||||
"Recipient email *": "Адресат электронной почты *",
|
||||
"Email subject *": "Тема письма *",
|
||||
"Email content *": "Содержимое письма *",
|
||||
"Sending...": "Отправка...",
|
||||
"Send": "Отправить",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Пожалуйста, не отправляйте незаконный контент, такой как политика, порнография и т. д."
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "Hakkında",
|
||||
"Privacy": "Gizlilik",
|
||||
"INBOX": "GİRİŞ",
|
||||
"Waiting for emails...": "E-Postalar Bekleniyor..."
|
||||
"Waiting for emails...": "E-Postalar Bekleniyor...",
|
||||
"Try it": "Deneyin",
|
||||
"Forward only, no storage": "Sadece ileri, depolama yok",
|
||||
"Sending email *": "E-posta gönderme *",
|
||||
"Sending name": "Gönderen adı",
|
||||
"Recipient email *": "Alıcı e-posta *",
|
||||
"Email subject *": "E-posta konusu *",
|
||||
"Email content *": "E-posta içeriği *",
|
||||
"Sending...": "Gönderiliyor...",
|
||||
"Send": "Gönder",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "Lütfen siyaset, pornografi vb. gibi yasa dışı içerikler göndermeyin"
|
||||
}
|
||||
@@ -16,5 +16,15 @@
|
||||
"About": "關於",
|
||||
"Privacy": "隱私政策",
|
||||
"INBOX": "收件匣",
|
||||
"Waiting for emails...": "等待電子郵件..."
|
||||
"Waiting for emails...": "等待電子郵件...",
|
||||
"Try it": "試試看",
|
||||
"Forward only, no storage": "僅轉發,不儲存",
|
||||
"Sending email *": "發送電子郵件 *",
|
||||
"Sending name": "發件人姓名",
|
||||
"Recipient email *": "收件者電子郵件 *",
|
||||
"Email subject *": "電子郵件主題 *",
|
||||
"Email content *": "電子郵件內容 *",
|
||||
"Sending...": "發送中...",
|
||||
"Send": "發送",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "請不要發送政治、色情等非法內容"
|
||||
}
|
||||
@@ -16,5 +16,16 @@
|
||||
"About": "关于",
|
||||
"Privacy": "隐私",
|
||||
"INBOX": "INBOX",
|
||||
"Waiting for emails...": "准备接收邮件..."
|
||||
"Waiting for emails...": "准备接收邮件...",
|
||||
"Vmail sender is beta now. ": "Vmail 发信公测中,",
|
||||
"Try it": "试试匿名发件",
|
||||
"Forward only, no storage": "仅转发,不存储",
|
||||
"Sending email *": "发送电子邮件 *",
|
||||
"Sending name": "发件人昵称",
|
||||
"Recipient email *": "收件人电子邮件 *",
|
||||
"Email subject *": "电子邮件主题 *",
|
||||
"Email content *": "电子邮件内容 *",
|
||||
"Sending...": "正在发送...",
|
||||
"Send": "发送",
|
||||
"Please do not send illegal content such as politics, pornography, etc": "请勿发送涉政、色情等违法内容"
|
||||
}
|
||||
Reference in new issue
Block a user