Skip to content

Commit

Permalink
Merge pull request #135 from VampireChicken12/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
VampireChicken12 authored Dec 1, 2023
2 parents 0c86734 + 4954223 commit f906ad8
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 236 deletions.
15 changes: 8 additions & 7 deletions src/components/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ export default function Settings() {
}
}

addNotification("success", t("pages.options.notifications.success.saved"));
addNotification("success", "pages.options.notifications.success.saved");
}
}
function resetOptions() {
addNotification("info", t("pages.options.notifications.info.reset"), "reset_settings");
addNotification("info", "pages.options.notifications.info.reset", "reset_settings");
}
function clearData() {
const userHasConfirmed = window.confirm(t("settings.clearData.confirmAlert"));
Expand All @@ -183,7 +183,7 @@ export default function Settings() {
void chrome.storage.local.set({ [key]: defaultSettings[key] as string });
}
}
addNotification("success", t("settings.clearData.allDataDeleted"));
addNotification("success", "settings.clearData.allDataDeleted");
}
}
const {
Expand Down Expand Up @@ -359,7 +359,7 @@ export default function Settings() {
}
}
// Show a success notification.
addNotification("success", t("settings.sections.importExportSettings.importButton.success"));
addNotification("success", "settings.sections.importExportSettings.importButton.success");
}
} catch (error) {
// Handle any import errors.
Expand Down Expand Up @@ -406,12 +406,12 @@ export default function Settings() {
a.click();

// Show a success notification.
addNotification("success", t("settings.sections.importExportSettings.exportButton.success"));
addNotification("success", "settings.sections.importExportSettings.exportButton.success");
}
};
// TODO: add "default player mode" setting (theater, fullscreen, etc.) feature
return (
<SettingsContext.Provider value={{ direction: localeDirection[settings.language], settings }}>
<SettingsContext.Provider value={{ direction: localeDirection[settings.language], i18nInstance, settings }}>
<div className="h-fit w-fit bg-[#f5f5f5] text-black dark:bg-[#181a1b] dark:text-white" dir={localeDirection[settings.language]}>
<h1 className="flex content-center items-center gap-3 text-xl font-bold sm:text-2xl md:text-3xl" dir={"ltr"}>
<img className="h-16 w-16 sm:h-16 sm:w-16" src="/icons/icon_128.png" />
Expand Down Expand Up @@ -726,7 +726,7 @@ export default function Settings() {
}
}

addNotification("success", t("pages.options.notifications.success.saved"));
addNotification("success", "pages.options.notifications.success.saved");
}}
title={t("settings.sections.bottomButtons.confirm.title")}
type="button"
Expand All @@ -751,6 +751,7 @@ export default function Settings() {
}
type SettingsContextProps = {
direction: "ltr" | "rtl";
i18nInstance: i18nInstanceType;
settings: configuration;
};
export const SettingsContext = createContext<SettingsContextProps | undefined>(undefined);
Expand Down
72 changes: 40 additions & 32 deletions src/components/Settings/components/SettingNotifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,56 @@ import { useNotifications } from "@/src/hooks";
import { cn } from "@/src/utils/utilities";
import { useAutoAnimate } from "@formkit/auto-animate/react";

import { useSettings } from "../Settings";

export default function SettingsNotifications() {
const { notifications, removeNotification } = useNotifications();
const [parentRef] = useAutoAnimate({ duration: 300 });
const {
i18nInstance: { t }
} = useSettings();
return (
<div id="notifications" ref={parentRef}>
{notifications.map((notification, index) => (
<div
className={cn("notification inverse relative bg-teal-600", {
"bg-blue-600": notification.type === "info",
"bg-green-600": notification.type === "success",
"bg-red-600": notification.type === "error",
"bg-yellow-600": notification.type === "warning"
})}
key={index}
>
{notification.action ? (
notification.action === "reset_settings" ? (
{notifications.map((notification, index) => {
const message: string = t(notification.message);
return (
<div
className={cn("notification inverse relative bg-teal-600", {
"bg-blue-600": notification.type === "info",
"bg-green-600": notification.type === "success",
"bg-red-600": notification.type === "error",
"bg-yellow-600": notification.type === "warning"
})}
key={index}
>
{notification.action ? (
notification.action === "reset_settings" ? (
<>
{message.split("\n").map((line, index) => (
<p key={index}>{line}</p>
))}
<button className="absolute right-[5px] top-[-1px] text-base font-normal" onClick={() => removeNotification(notification)}>
&times;
</button>
</>
) : null
) : (
<>
{notification.message.split("\n").map((line, index) => (
<p key={index}>{line}</p>
))}
{message}
<button className="absolute right-[5px] top-[-1px] text-base font-normal" onClick={() => removeNotification(notification)}>
&times;
</button>
</>
) : null
) : (
<>
{notification.message}
<button className="absolute right-[5px] top-[-1px] text-base font-normal" onClick={() => removeNotification(notification)}>
&times;
</button>
</>
)}
<div
className="absolute bottom-0 left-0 h-1 rounded-b bg-[#0086ff]"
id={`${notification.type}_notification_${notification.message.split(/s /).join("_")}_progress_bar`}
key={index}
style={{ width: `${notification.progress ?? 100}%` }}
></div>
</div>
))}
)}
<div
className="absolute bottom-0 left-0 h-1 rounded-b bg-[#0086ff]"
id={`${notification.type}_notification_${message.split(/s /).join("_")}_progress_bar`}
key={index}
style={{ width: `${notification.progress ?? 100}%` }}
></div>
</div>
);
})}
</div>
);
}
8 changes: 6 additions & 2 deletions src/hooks/useNotifications/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import type { Notification, NotificationAction, NotificationType } from "@/src/t

import { createContext } from "react";

export type AddNotification = (type: NotificationType, message: Notification["message"], action?: NotificationAction) => void;

export type RemoveNotification = (notification: Notification) => void;

export type NotificationsContextProps = {
addNotification: (type: NotificationType, message: string, action?: NotificationAction) => void;
addNotification: AddNotification;
notifications: Notification[];
removeNotification: (notification: Notification) => void;
removeNotification: RemoveNotification;
};
export const NotificationsContext = createContext<NotificationsContextProps | undefined>(undefined);
14 changes: 7 additions & 7 deletions src/hooks/useNotifications/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { Notification, NotificationAction, NotificationType } from "@/src/types";
import type { Notification } from "@/src/types";

import { isNotStrictEqual } from "@/src/utils/utilities";
import React, { type ReactElement, useEffect, useState } from "react";
import { type ReactElement, useEffect, useState } from "react";

import { NotificationsContext, type NotificationsContextProps } from "./context";
import { type AddNotification, NotificationsContext, type NotificationsContextProps, type RemoveNotification } from "./context";
type NotificationProviderProps = { children: ReactElement | ReactElement[] };
export const NotificationsProvider = ({ children }: NotificationProviderProps) => {
const [notifications, setNotifications] = useState<Notification[]>([]);

function addNotification(type: NotificationType, message: string, action?: NotificationAction) {
const addNotification: AddNotification = (type, message, action) => {
const existingNotification = notifications.find((n) => n.message === message && n.type === type);
if (existingNotification) {
return;
Expand All @@ -24,10 +24,10 @@ export const NotificationsProvider = ({ children }: NotificationProviderProps) =
removeNotification(notification);
}, removeNotificationAfterMs);
}
}
function removeNotification(notification: Notification) {
};
const removeNotification: RemoveNotification = (notification) => {
setNotifications((notifications) => notifications.filter(isNotStrictEqual(notification)));
}
};
useEffect(() => {
const interval = setInterval(() => {
setNotifications((notifications) => {
Expand Down
64 changes: 32 additions & 32 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,40 @@ import { type Resource, createInstance } from "i18next";

import { waitForSpecificMessage } from "../utils/utilities";
export const availableLocales = [
"ca-ES",
"cs-CZ",
"de-DE",
"en-US",
"es-ES",
"fa-IR",
"fr-FR",
"he-IL",
"hi-IN",
"it-IT",
"ja-JP",
"pl-PL",
"pt-BR",
"ru-RU",
"tr-TR",
"zh-CN"
"ca-ES",
"cs-CZ",
"de-DE",
"en-US",
"es-ES",
"fa-IR",
"fr-FR",
"he-IL",
"hi-IN",
"it-IT",
"ja-JP",
"pl-PL",
"pt-BR",
"ru-RU",
"tr-TR",
"zh-CN"
] as const;
export const translationPercentages: Record<AvailableLocales, number> = {
"ca-ES": 0,
"cs-CZ": 0,
"de-DE": 4,
"es-ES": 19,
"fa-IR": 0,
"fr-FR": 0,
"he-IL": 0,
"hi-IN": 0,
"it-IT": 0,
"ja-JP": 100,
"pl-PL": 3,
"pt-BR": 0,
"ru-RU": 100,
"tr-TR": 66,
"zh-CN": 75,
"en-US": 100
"ca-ES": 0,
"cs-CZ": 0,
"de-DE": 4,
"en-US": 100,
"es-ES": 19,
"fa-IR": 0,
"fr-FR": 0,
"he-IL": 0,
"hi-IN": 0,
"it-IT": 0,
"ja-JP": 100,
"pl-PL": 3,
"pt-BR": 0,
"ru-RU": 100,
"tr-TR": 66,
"zh-CN": 75
};
export const localeDirection: Record<AvailableLocales, "ltr" | "rtl"> = {
"ca-ES": "ltr",
Expand Down
5 changes: 3 additions & 2 deletions src/pages/popup/index.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
body {
width: max-content;
width: fit-content;
margin: 12px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

min-width: 400px;
max-width: 640px;
position: relative;
overflow-y: scroll;
}
3 changes: 2 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ParseKeys, TOptions } from "i18next";
import type { YouTubePlayer } from "youtube-player/dist/types";

import z from "zod";
Expand Down Expand Up @@ -181,7 +182,7 @@ export type NotificationAction = "reset_settings" | undefined;

export type Notification = {
action: NotificationAction;
message: string;
message: ParseKeys<"en-US", TOptions, undefined>;
progress?: number;
removeAfterMs?: number;
timestamp?: number;
Expand Down
27 changes: 27 additions & 0 deletions src/utils/checkLocalesForMissingKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type EnUS from "public/locales/en-US.json";

import { availableLocales } from "../i18n";
import { type LocaleFile, flattenLocaleValues, getLocaleFile } from "./plugins/utils";
function checkForMissingKeys(englishFile: LocaleFile, localeFile: LocaleFile) {
const { keys: englishKeys } = flattenLocaleValues(englishFile);
const { keys: localeKeys } = flattenLocaleValues(localeFile);
if (englishKeys.length !== localeKeys.length) {
const missingKeys = englishKeys.filter((key) => !localeKeys.includes(key));
const message = `${(localeFile as unknown as EnUS)["langCode"]} is missing ${missingKeys.length} keys\nMissing keys:\n${missingKeys.join(", ")}`;
return message;
}
return false;
}
export default function checkLocalesForMissingKeys() {
const englishFile = getLocaleFile("en-US");
const missingKeys = availableLocales
.filter((availableLocales) => availableLocales !== "en-US")
.map((locale) => {
const localeFile = getLocaleFile(locale);
return checkForMissingKeys(englishFile, localeFile);
})
.filter(Boolean);
if (missingKeys.length) {
throw new Error(missingKeys.join("\n\n"));
}
}
Loading

0 comments on commit f906ad8

Please sign in to comment.