Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit e5594d6

Browse files
committed
Localisation Support,Resolved #10, 5 Different Languages Supported(hi,fr,ru,en,es
1 parent 8dfd53d commit e5594d6

File tree

20 files changed

+355
-50
lines changed

20 files changed

+355
-50
lines changed

ReadMe.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Some features may be lacking as it is a beta version but the bundled features ar
4141
- A Better Card View and a Table View
4242
- Rich Text Editing Experience to send a mail
4343
- General Settings to configure app specs
44+
- Available in 5 Different Languages (Localisation)
45+
- Download or Export Mails as CSV file
4446

4547
# Built With
4648

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"react-dom": "^17.0.2",
3434
"react-draft-wysiwyg": "^1.14.7",
3535
"react-google-login": "^5.2.2",
36+
"react-i18next": "^11.16.7",
3637
"react-icons": "^4.3.1",
3738
"react-redux": "^7.2.6",
3839
"react-router-dom": "^6.1.1",

src/renderer/components/ListMail/ListMail.jsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,10 @@ function ListMail({
112112
subject={data && data?.sender[0]?.name}
113113
time={istoDay(data)}
114114
isstarred={CheckFlag(data, "flagged")}
115-
setisAnyMailOpen={setisAnyMailOpen}
116-
setopenedmail={setopenedmail}
117115
messageId={data.messageId}
118116
mailObject={data}
119117
read={CheckFlag(data, "seen")}
120118
key={index.toString()}
121-
read={CheckFlag(data, "seen")}
122119
CheckForSelectedDiv={(val, id) => {
123120
try {
124121
CheckForSelectedDiv(

src/renderer/components/ListMail/ListTopIcons.jsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from "react-icons/md";
99
import { Link, useLocation } from "react-router-dom";
1010
import PaginationComp from "./PaginationComp";
11+
import { useTranslation } from 'react-i18next';
1112

1213
function ListTopIcons({
1314
Refresh,
@@ -19,7 +20,10 @@ function ListTopIcons({
1920
setGridView,
2021
message,
2122
}) {
23+
2224
const location = useLocation();
25+
const { t } = useTranslation();
26+
2327
return (
2428
<div className="flex flex-col text-text ">
2529
<div className=" flex mt-4 items-center justify-evenly">
@@ -28,28 +32,28 @@ function ListTopIcons({
2832
size={30}
2933
className="ml-1 mr-2 cursor-pointer "
3034
onClick={Refresh}
31-
title="Refresh"
35+
title={t("Refresh")}
3236
/>
3337
{GridView == 2 && (
3438
<MdViewList
3539
className="mr-2 cursor-pointer "
3640
size={30}
3741
onClick={() => setGridView(0)}
38-
title="List View"
42+
title={t("ListView")}
3943
/>
4044
)}
4145
{GridView == 0 && (
4246
<MdGridView
4347
className="mr-2 cursor-pointer "
4448
size={30}
4549
onClick={() => setGridView(1)}
46-
title="Grid View"
50+
title={t("GridView")}
4751
/>
4852
)}
4953
{GridView == 1 && (
5054
<MdViewCompact
5155
className="mr-2 cursor-pointer "
52-
title="Default View"
56+
title={t("DefaultView")}
5357
size={30}
5458
onClick={() => setGridView(2)}
5559
/>
@@ -64,15 +68,15 @@ function ListTopIcons({
6468
}}
6569
>
6670
<MdTableView
67-
title="table view"
71+
title={t("TableView")}
6872
className="mr-2 cursor-pointer "
6973
size={30}
7074
/>
7175
</Link>
7276
}
7377
</div>
7478
<span className="font-mono font-semibold mr-2">
75-
{Data?.length} Fetched Messages
79+
{Data?.length} {t("FetchedMessages")}
7680
</span>
7781
<div className="hidden lg:flex">
7882
<PaginationComp

src/renderer/components/Loading/Loading.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import React from "react";
22
import TitleBar from "~/components/TopBar/WindowBar";
3+
import { useTranslation } from 'react-i18next';
34

45
function Loading({ icon }) {
6+
const { t } = useTranslation()
57
return (
68
<div className="bg-LoadingBackground text-LoadingText">
79
<>
810
<TitleBar icon={icon} />
911
<div className="flex flex-col justify-center items-center h-[calc(100vh_-_2rem)]">
1012
<div className="flex flex-col items-center ">
1113
<h1 className="text-3xl font-bold capitalize leading-loose mr-4 ">
12-
hang on while luca is setting up mail for you
14+
{t("loadingtag")}
1315
</h1>
1416
<img
1517
src="https://camo.githubusercontent.com/09b4eefc1e15caef9a2e732fba9d4a5c4baf1a57c8a1ea21bcb3b639a3c5457d/68747470733a2f2f696d6775722e636f6d2f74637258454b4b2e706e67"

src/renderer/components/Promotional/Banner.jsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import React from "react";
2-
import { constant } from "./constant";
32
import bannerimg from "../../../main/helpers/assets/promote.svg";
3+
import { useTranslation } from 'react-i18next';
4+
45
function Banner({ composeopen, setcomposeopen }) {
5-
const { title, tagline, description, PromotebtnText } = constant.Banner[0];
6+
const { t } = useTranslation();
67
return (
78
<aside className="relative overflow-hidden bg-BannerCardBackground text-BannerCardText rounded-xl lg:flex max-w-screen-xl px-4 shadow-2xl mx-auto ">
89
<div className="w-full p-12 text-center lg:w-1/2 sm:p-16 lg:p-24 lg:text-left">
910
<div className="max-w-xl mx-auto lg:ml-0">
10-
<p className="text-sm text-BannerCardTitle font-medium">{title}</p>
11-
12-
<p className="mt-2 text-2xl font-bold sm:text-3xl">{tagline}</p>
11+
<p className="text-sm text-BannerCardTitle font-medium">{t("title")}</p>
1312

14-
<p className="hidden lg:mt-4 lg:block">{description}</p>
13+
<p className="mt-2 text-2xl font-bold sm:text-3xl">{t("tagline")}</p>
1514

15+
<p className="hidden lg:mt-4 lg:block">{t("description")}</p>
1616
<button
1717
href=""
1818
onClick={() => setcomposeopen(!composeopen)}
1919
className="inline-block px-5 py-3 mt-8 text-sm font-medium bg-BannerCardButtonBackground rounded-tl-2xl rounded-br-2xl text-BannerCardButtonText shadow-lg "
2020
>
21-
{PromotebtnText}
21+
{t("PromotebtnText")}
2222
</button>
2323
</div>
2424
</div>

src/renderer/components/Promotional/Stats.jsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,41 @@
11
import React from "react";
2-
import { constant } from "./constant";
2+
import { useTranslation } from 'react-i18next';
3+
34
function Stats({ uname, Data, UnreadCount, StarredCount }) {
5+
const { t } = useTranslation();
6+
47
return (
58
<div>
69
<section className="text-StatCardText ">
710
<div className="max-w-screen-xl px-0 py-16 mx-auto ">
811
<div className="max-w-xl ">
912
<h2 className="text-2xl font-bold text-white sm:text-3xl">
10-
{constant?.stats[0].title},{uname?.split("@")[0]}
13+
{t("stattitle")},{uname?.split("@")[0]}
1114
</h2>
12-
<p className="mt-4 sm:text-xl">{constant?.stats[0].tagline}</p>
15+
<p className="mt-4 sm:text-xl">{t("stattagline")}</p>
1316
</div>
1417
<ul className="grid grid-cols-1 gap-8 mt-8 sm:grid-cols-2 lg:grid-cols-3">
1518
<li className="p-8 shadow-xl rounded-xl bg-StatCardBackground">
1619
<p className="text-3xl font-extrabold">{Data?.length}</p>
1720
<p className="mt-1 text-xl font-medium">
1821
{" "}
19-
{constant?.stats[0].stat1}
22+
{t("stat1")}
2023
</p>
2124
</li>
2225

2326
<li className="p-8 shadow-xl rounded-xl bg-StatCardBackground">
2427
<p className="text-3xl font-extrabold">{UnreadCount}</p>
2528
<p className="mt-1 text-xl font-medium">
2629
{" "}
27-
{constant?.stats[0].stat2}
30+
{t("stat2")}
2831
</p>
2932
</li>
3033

3134
<li className="p-8 shadow-xl rounded-xl bg-StatCardBackground">
3235
<p className="text-3xl font-extrabold">{StarredCount}</p>
3336
<p className="mt-1 text-xl font-medium">
3437
{" "}
35-
{constant?.stats[0].stat3}
38+
{t("stat3")}
3639
</p>
3740
</li>
3841
</ul>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { useState, useEffect } from "react";
2+
import { MdArrowDropDown, MdCheck } from "react-icons/md";
3+
4+
const LanguageSelect = ({ toggle, settoggle, selected, onClickHandler, Data }) => {
5+
const [changedval, setchangedval] = useState(selected);
6+
7+
useEffect(() => {
8+
setchangedval(selected);
9+
}, [selected]);
10+
11+
return (
12+
<div className="relative inline-block text-left ">
13+
<div>
14+
<button
15+
onClick={() => settoggle(!toggle)}
16+
type="button"
17+
className="inline-flex justify-center w-full text-BannerCardButtonText bg-BannerCardButtonBackground rounded-tl-2xl rounded-br-2xl shadow-lg px-4 py-2 text-sm font-bold "
18+
id="menu-button"
19+
aria-expanded="true"
20+
aria-haspopup="true"
21+
>
22+
{selected}
23+
<MdArrowDropDown className="-mr-1 ml-2 h-5 w-5" />
24+
</button>
25+
</div>
26+
{toggle && (
27+
<div
28+
className="origin-top-right absolute right-0 mt-2 px-5 text-text rounded-md shadow-lg bg-MailCardBackground ring-opacity-5 "
29+
role="menu"
30+
aria-orientation="vertical"
31+
aria-labelledby="menu-button"
32+
tabindex="-1"
33+
>
34+
{Data?.map((val) => {
35+
return (
36+
<div
37+
className="flex items-center cursor-pointer my-2 "
38+
role="none"
39+
>
40+
{changedval != val.code ? (
41+
<div className=" p-1 h-2 w-2 rounded-full" />
42+
) : (
43+
<MdCheck size={18} />
44+
)}
45+
<div
46+
onClick={() => onClickHandler(val.code)}
47+
className="text-text block px-4 py-2 text-sm no-underline p-2"
48+
>
49+
{val.label}
50+
</div>
51+
</div>
52+
);
53+
})}
54+
</div>
55+
)}
56+
</div>
57+
);
58+
};
59+
60+
export default LanguageSelect;

src/renderer/components/Settings/Settings.jsx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import Button from "../Basic/Button";
99
import InputField from "../Login/InputField";
1010
import GeneralSettings from "./GeneralSettings";
1111
import ThemeSettings from "./ThemeSettings";
12+
import { useTranslation } from 'react-i18next';
13+
import { LanguagesSupported } from "../../i18n/config";
14+
import LanguageSelect from "./LanguageSelect";
1215
const fs = require("fs");
1316

1417
function Settings({ params }) {
@@ -21,6 +24,8 @@ function Settings({ params }) {
2124
const [activelabel, setactivelabel] = useState(
2225
SettingTypes["TabHeaders"][0].label
2326
);
27+
const [selected, setselected] = useState("English");
28+
const [toggle, settoggle] = useState(false);
2429
const [CustomThemeFile, setCustomThemeFile] = useState();
2530
function OnApplyChanges() {
2631
if (fetchlimit && fetchlimit > 0) {
@@ -35,7 +40,12 @@ function Settings({ params }) {
3540
StoreSettings();
3641
}
3742
}
38-
43+
44+
const { i18n } = useTranslation();
45+
46+
function changeLanguage(e) {
47+
i18n.changeLanguage(e);
48+
}
3949

4050
function StoreSettings(flimit) {
4151
localStorage.setItem("Settings", JSON.stringify(Checked));
@@ -51,9 +61,8 @@ function Settings({ params }) {
5161
{SettingTypes?.TabHeaders?.map((e) => (
5262
<button
5363
onClick={() => setactivelabel(e.label)}
54-
className={` p-4 text-SettingsCardTitle -mb-px border-b border-b-SideBarBackground ${
55-
activelabel == e.label && "border-b-primary"
56-
} `}
64+
className={` p-4 text-SettingsCardTitle -mb-px border-b border-b-SideBarBackground ${activelabel == e.label && "border-b-primary"
65+
} `}
5766
title={e.label}
5867
>
5968
<div class="flex items-center justify-center">{e.label}</div>
@@ -81,14 +90,25 @@ function Settings({ params }) {
8190
}}
8291
Data={e}
8392
/>
93+
8494
))}
85-
<div className="mt-4">
95+
<div className="mt-4 mb-4">
8696
<InputField
8797
placeholder="Enter Number of Mails to fetch at once"
8898
value={fetchlimit}
8999
updatedValue={setfetchlimit}
90100
/>
91101
</div>
102+
<div className="flex items-end justify-items-end text-SettingsCardText justify-between">
103+
Select your preferred language
104+
<LanguageSelect
105+
Data={LanguagesSupported}
106+
selected={selected}
107+
settoggle={settoggle}
108+
toggle={toggle}
109+
onClickHandler={(val) => changeLanguage(val)}
110+
/>
111+
</div>
92112
<Button handler={OnApplyChanges} btntext="save changes" />
93113
</>
94114
)}

src/renderer/components/Settings/ThemeSettings.jsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ThemeSelect from "./ThemeSelect";
66
import useComponentVisible from "~/utils/TouchBehaviour";
77
import { applyTheme } from "../../themes/themeutil";
88
import Button from "../Basic/Button";
9+
import { useTranslation } from 'react-i18next';
910
import { WriteFile, readFile, DeleteFile } from "../../lib/fileAction";
1011
const path = require("path");
1112
const fs = require("fs");
@@ -17,6 +18,7 @@ const ThemeSettings = ({ CustomThemeFile, setCustomThemeFile, user }) => {
1718
const [Data, setData] = useState();
1819
const [Themes, setThemes] = useState();
1920
let themepath = path.join(user?.auth?.user, "conf", "theme");
21+
const { t } = useTranslation()
2022

2123
async function CheckThemes() {
2224
let themeObject = await ParseContent(themepath);
@@ -102,10 +104,9 @@ const ThemeSettings = ({ CustomThemeFile, setCustomThemeFile, user }) => {
102104
<div ref={ref} className="">
103105
<div className="flex mt-4 justify-between pb-2 border-b border-b-SideBarBackground">
104106
<div className="flex flex-col">
105-
<span className="text-md ">Upload custom Theme</span>
107+
<span className="text-md ">{t("customtheme")}</span>
106108
<span className="text-xs opacity-75">
107-
you can upload your custom json theme file,you can find default
108-
theme json file in github repo
109+
{t("uploadtheme")}
109110
</span>
110111
</div>
111112
<div>
@@ -128,11 +129,12 @@ const ThemeSettings = ({ CustomThemeFile, setCustomThemeFile, user }) => {
128129
</div>
129130
<div className="flex mt-4 justify-between pb-2 border-b border-b-SideBarBackground">
130131
<div className="flex flex-col">
131-
<span className="text-md ">Select Preferred Theme</span>
132+
<span className="text-md ">{t("preferredtheme")}</span>
132133
<span className="text-xs opacity-75">
133134
{Themes && Object.keys(Themes?.ListOfThemes)?.length > 0
134-
? "you have uploaded a custom theme file choose from one of them "
135-
: "choose from default themes available,you can upload custom theme if you dont like these themes"}
135+
? `${t("customselect")}`
136+
: `${t("defaultselect")}`
137+
}
136138
</span>
137139
</div>
138140
<div>
@@ -148,10 +150,9 @@ const ThemeSettings = ({ CustomThemeFile, setCustomThemeFile, user }) => {
148150
{Themes && Object.keys(Themes?.ListOfThemes)?.length > 0 && (
149151
<div className="flex mt-4 justify-between pb-2 border-b border-b-SideBarBackground">
150152
<div className="flex flex-col">
151-
<span className="text-md ">Delete Custom Theme File</span>
153+
<span className="text-md ">{t("deletetheme")}</span>
152154
<span className="text-xs opacity-75">
153-
you can choose themes from default files by removing custom theme
154-
file
155+
{t("defaultchoose")}
155156
</span>
156157
</div>
157158
<div>
@@ -163,7 +164,7 @@ const ThemeSettings = ({ CustomThemeFile, setCustomThemeFile, user }) => {
163164
</div>
164165
</div>
165166
)}
166-
<Button handler={ApplyThemeConf} btntext="apply theme settings" />
167+
<Button handler={ApplyThemeConf} btntext={t("applytheme")} />
167168
</div>
168169
);
169170
};

0 commit comments

Comments
 (0)