mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 22:07:15 +00:00
feat: implement dark mode
This commit is contained in:
parent
07e0bb2d4c
commit
3488cd04c0
@ -87,7 +87,7 @@ func getUserSetting(ctx context.Context, s *store.Store, userID int32) (*apiv2pb
|
|||||||
userSetting := &apiv2pb.UserSetting{
|
userSetting := &apiv2pb.UserSetting{
|
||||||
Id: userID,
|
Id: userID,
|
||||||
Locale: apiv2pb.UserSetting_LOCALE_EN,
|
Locale: apiv2pb.UserSetting_LOCALE_EN,
|
||||||
ColorTheme: apiv2pb.UserSetting_COLOR_THEME_LIGHT,
|
ColorTheme: apiv2pb.UserSetting_COLOR_THEME_SYSTEM,
|
||||||
}
|
}
|
||||||
for _, setting := range userSettings {
|
for _, setting := range userSettings {
|
||||||
if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
|
if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
|
||||||
@ -123,6 +123,8 @@ func convertUserSettingLocaleFromStore(locale storepb.LocaleUserSetting) apiv2pb
|
|||||||
|
|
||||||
func convertUserSettingColorThemeToStore(colorTheme apiv2pb.UserSetting_ColorTheme) storepb.ColorThemeUserSetting {
|
func convertUserSettingColorThemeToStore(colorTheme apiv2pb.UserSetting_ColorTheme) storepb.ColorThemeUserSetting {
|
||||||
switch colorTheme {
|
switch colorTheme {
|
||||||
|
case apiv2pb.UserSetting_COLOR_THEME_SYSTEM:
|
||||||
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_SYSTEM
|
||||||
case apiv2pb.UserSetting_COLOR_THEME_LIGHT:
|
case apiv2pb.UserSetting_COLOR_THEME_LIGHT:
|
||||||
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT
|
||||||
case apiv2pb.UserSetting_COLOR_THEME_DARK:
|
case apiv2pb.UserSetting_COLOR_THEME_DARK:
|
||||||
@ -134,6 +136,8 @@ func convertUserSettingColorThemeToStore(colorTheme apiv2pb.UserSetting_ColorThe
|
|||||||
|
|
||||||
func convertUserSettingColorThemeFromStore(colorTheme storepb.ColorThemeUserSetting) apiv2pb.UserSetting_ColorTheme {
|
func convertUserSettingColorThemeFromStore(colorTheme storepb.ColorThemeUserSetting) apiv2pb.UserSetting_ColorTheme {
|
||||||
switch colorTheme {
|
switch colorTheme {
|
||||||
|
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_SYSTEM:
|
||||||
|
return apiv2pb.UserSetting_COLOR_THEME_SYSTEM
|
||||||
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT:
|
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT:
|
||||||
return apiv2pb.UserSetting_COLOR_THEME_LIGHT
|
return apiv2pb.UserSetting_COLOR_THEME_LIGHT
|
||||||
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK:
|
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useColorScheme } from "@mui/joy";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import DemoBanner from "./components/DemoBanner";
|
import DemoBanner from "./components/DemoBanner";
|
||||||
@ -7,6 +8,7 @@ import useUserStore from "./stores/v1/user";
|
|||||||
import { WorkspaceSetting } from "./types/proto/api/v2/workspace_service";
|
import { WorkspaceSetting } from "./types/proto/api/v2/workspace_service";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const { mode } = useColorScheme();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const [workspaceSetting, setWorkspaceSetting] = useState<WorkspaceSetting>(WorkspaceSetting.fromPartial({}));
|
const [workspaceSetting, setWorkspaceSetting] = useState<WorkspaceSetting>(WorkspaceSetting.fromPartial({}));
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@ -47,6 +49,39 @@ function App() {
|
|||||||
document.body.insertAdjacentElement("beforeend", styleEl);
|
document.body.insertAdjacentElement("beforeend", styleEl);
|
||||||
}, [workspaceSetting.customStyle]);
|
}, [workspaceSetting.customStyle]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const root = document.documentElement;
|
||||||
|
if (mode === "light") {
|
||||||
|
root.classList.remove("dark");
|
||||||
|
} else if (mode === "dark") {
|
||||||
|
root.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
if (darkMediaQuery.matches) {
|
||||||
|
root.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
root.classList.remove("dark");
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleColorSchemeChange = (e: MediaQueryListEvent) => {
|
||||||
|
if (e.matches) {
|
||||||
|
root.classList.add("dark");
|
||||||
|
} else {
|
||||||
|
root.classList.remove("dark");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
darkMediaQuery.addEventListener("change", handleColorSchemeChange);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("failed to initial color scheme listener", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
darkMediaQuery.removeEventListener("change", handleColorSchemeChange);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [mode]);
|
||||||
|
|
||||||
return !loading ? (
|
return !loading ? (
|
||||||
<>
|
<>
|
||||||
<DemoBanner />
|
<DemoBanner />
|
||||||
|
@ -26,17 +26,17 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
|
|||||||
{analytics ? (
|
{analytics ? (
|
||||||
<>
|
<>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<p className="w-full h-8 px-2">{t("analytics.top-sources")}</p>
|
<p className="w-full h-8 px-2 dark:text-gray-500">{t("analytics.top-sources")}</p>
|
||||||
<div className="w-full mt-1 overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg">
|
<div className="w-full mt-1 overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg dark:ring-zinc-800">
|
||||||
<div className="w-full divide-y divide-gray-300">
|
<div className="w-full divide-y divide-gray-300 dark:divide-zinc-700">
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="py-2 px-2 text-left font-semibold text-sm text-gray-500">{t("analytics.source")}</span>
|
<span className="py-2 px-2 text-left font-semibold text-sm text-gray-500">{t("analytics.source")}</span>
|
||||||
<span className="py-2 pr-2 text-right font-semibold text-sm text-gray-500">{t("analytics.visitors")}</span>
|
<span className="py-2 pr-2 text-right font-semibold text-sm text-gray-500">{t("analytics.visitors")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full divide-y divide-gray-200">
|
<div className="w-full divide-y divide-gray-200 dark:divide-zinc-800">
|
||||||
{analytics.referenceData.map((reference) => (
|
{analytics.referenceData.map((reference) => (
|
||||||
<div key={reference.name} className="w-full flex flex-row justify-between items-center">
|
<div key={reference.name} className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="whitespace-nowrap py-2 px-2 text-sm truncate text-gray-900">
|
<span className="whitespace-nowrap py-2 px-2 text-sm truncate text-gray-900 dark:text-gray-500">
|
||||||
{reference.name ? (
|
{reference.name ? (
|
||||||
<a className="hover:underline hover:text-blue-600" href={reference.name} target="_blank">
|
<a className="hover:underline hover:text-blue-600" href={reference.name} target="_blank">
|
||||||
{reference.name}
|
{reference.name}
|
||||||
@ -55,24 +55,24 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
|
|||||||
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="w-full h-8 px-2 flex flex-row justify-between items-center">
|
<div className="w-full h-8 px-2 flex flex-row justify-between items-center">
|
||||||
<span>{t("analytics.devices")}</span>
|
<span className="dark:text-gray-500">{t("analytics.devices")}</span>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className={`whitespace-nowrap border-b-2 px-1 text-sm font-medium ${
|
className={`whitespace-nowrap border-b-2 px-1 text-sm font-medium ${
|
||||||
selectedDeviceTab === "browser"
|
selectedDeviceTab === "browser"
|
||||||
? "border-blue-600 text-blue-600"
|
? "border-blue-600 text-blue-600"
|
||||||
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700"
|
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:hover:border-zinc-700"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSelectedDeviceTab("browser")}
|
onClick={() => setSelectedDeviceTab("browser")}
|
||||||
>
|
>
|
||||||
{t("analytics.browser")}
|
{t("analytics.browser")}
|
||||||
</button>
|
</button>
|
||||||
<span className="text-gray-200 font-mono mx-1">/</span>
|
<span className="text-gray-200 font-mono mx-1 dark:text-gray-500">/</span>
|
||||||
<button
|
<button
|
||||||
className={`whitespace-nowrap border-b-2 px-1 text-sm font-medium ${
|
className={`whitespace-nowrap border-b-2 px-1 text-sm font-medium ${
|
||||||
selectedDeviceTab === "os"
|
selectedDeviceTab === "os"
|
||||||
? "border-blue-600 text-blue-600"
|
? "border-blue-600 text-blue-600"
|
||||||
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700"
|
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:hover:border-zinc-700"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSelectedDeviceTab("os")}
|
onClick={() => setSelectedDeviceTab("os")}
|
||||||
>
|
>
|
||||||
@ -81,17 +81,19 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full mt-1 overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg">
|
<div className="w-full mt-1 overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg dark:ring-zinc-800">
|
||||||
{selectedDeviceTab === "browser" ? (
|
{selectedDeviceTab === "browser" ? (
|
||||||
<div className="w-full divide-y divide-gray-300">
|
<div className="w-full divide-y divide-gray-300 dark:divide-zinc-700">
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">{t("analytics.browsers")}</span>
|
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">{t("analytics.browsers")}</span>
|
||||||
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">{t("analytics.visitors")}</span>
|
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">{t("analytics.visitors")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full divide-y divide-gray-200">
|
<div className="w-full divide-y divide-gray-200 dark:divide-zinc-800">
|
||||||
{analytics.browserData.map((reference) => (
|
{analytics.browserData.map((reference) => (
|
||||||
<div key={reference.name} className="w-full flex flex-row justify-between items-center">
|
<div key={reference.name} className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="whitespace-nowrap py-2 px-2 text-sm text-gray-900 truncate">{reference.name || "Unknown"}</span>
|
<span className="whitespace-nowrap py-2 px-2 text-sm text-gray-900 truncate dark:text-gray-500">
|
||||||
|
{reference.name || "Unknown"}
|
||||||
|
</span>
|
||||||
<span className="whitespace-nowrap py-2 pr-2 text-sm text-gray-500 text-right shrink-0">{reference.count}</span>
|
<span className="whitespace-nowrap py-2 pr-2 text-sm text-gray-500 text-right shrink-0">{reference.count}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const BetaBadge = () => {
|
const BetaBadge = () => {
|
||||||
return (
|
return (
|
||||||
<div className="text-xs border px-1 text-gray-500 bg-gray-100 rounded-full">
|
<div className="text-xs border px-1 text-gray-500 bg-gray-100 rounded-full dark:bg-zinc-800 dark:border-zinc-700">
|
||||||
<span>Beta</span>
|
<span>Beta</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -230,16 +230,16 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-3 text-sm text-gray-500 w-full bg-gray-100 border border-gray-200 px-2 py-1 rounded-md">
|
<p className="mt-3 text-sm text-gray-500 w-full bg-gray-100 border border-gray-200 dark:bg-zinc-800 dark:border-zinc-700 dark:text-gray-400 px-2 py-1 rounded-md">
|
||||||
{t(`shortcut.visibility.${state.shortcutCreate.visibility.toLowerCase()}.description`)}
|
{t(`shortcut.visibility.${state.shortcutCreate.visibility.toLowerCase()}.description`)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Divider className="text-gray-500">Optional</Divider>
|
<Divider className="text-gray-500">Optional</Divider>
|
||||||
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden my-3">
|
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden my-3 dark:border-zinc-800">
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100",
|
"w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800",
|
||||||
showAdditionalFields ? "bg-gray-100 border-b" : ""
|
showAdditionalFields ? "bg-gray-100 border-b dark:bg-zinc-800 dark:border-b-zinc-700" : ""
|
||||||
)}
|
)}
|
||||||
onClick={() => setShowAdditionalFields(!showAdditionalFields)}
|
onClick={() => setShowAdditionalFields(!showAdditionalFields)}
|
||||||
>
|
>
|
||||||
@ -275,11 +275,12 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden">
|
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden dark:border-zinc-800">
|
||||||
<div
|
<div
|
||||||
className={`w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100 ${
|
className={classnames(
|
||||||
showOpenGraphMetadata ? "bg-gray-100 border-b" : ""
|
"w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800",
|
||||||
}`}
|
showOpenGraphMetadata ? "bg-gray-100 border-b dark:bg-zinc-800 dark:border-b-zinc-700" : ""
|
||||||
|
)}
|
||||||
onClick={() => setShowOpenGraphMetadata(!showOpenGraphMetadata)}
|
onClick={() => setShowOpenGraphMetadata(!showOpenGraphMetadata)}
|
||||||
>
|
>
|
||||||
<span className="text-sm flex flex-row justify-start items-center">
|
<span className="text-sm flex flex-row justify-start items-center">
|
||||||
|
@ -40,32 +40,32 @@ const ShortcutActionsDropdown = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
actionsClassName="!w-32"
|
actionsClassName="!w-32 dark:text-gray-500"
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
{havePermission && (
|
{havePermission && (
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={() => setShowEditDialog(true)}
|
onClick={() => setShowEditDialog(true)}
|
||||||
>
|
>
|
||||||
<Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
|
<Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={() => setShowQRCodeDialog(true)}
|
onClick={() => setShowQRCodeDialog(true)}
|
||||||
>
|
>
|
||||||
<Icon.QrCode className="w-4 h-auto mr-2" /> QR Code
|
<Icon.QrCode className="w-4 h-auto mr-2" /> QR Code
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={gotoAnalytics}
|
onClick={gotoAnalytics}
|
||||||
>
|
>
|
||||||
<Icon.BarChart2 className="w-4 h-auto mr-2" /> {t("analytics.self")}
|
<Icon.BarChart2 className="w-4 h-auto mr-2" /> {t("analytics.self")}
|
||||||
</button>
|
</button>
|
||||||
{havePermission && (
|
{havePermission && (
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleDeleteShortcutButtonClick(shortcut);
|
handleDeleteShortcutButtonClick(shortcut);
|
||||||
}}
|
}}
|
||||||
|
@ -39,7 +39,11 @@ const ShortcutView = (props: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={classNames("group px-4 py-3 w-full flex flex-col justify-start items-start border rounded-lg hover:shadow")}>
|
<div
|
||||||
|
className={classNames(
|
||||||
|
"group px-4 py-3 w-full flex flex-col justify-start items-start border rounded-lg hover:shadow dark:border-zinc-700"
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div className="w-[calc(100%-16px)] flex flex-row justify-start items-center mr-1 shrink-0">
|
<div className="w-[calc(100%-16px)] flex flex-row justify-start items-center mr-1 shrink-0">
|
||||||
<Link to={`/shortcut/${shortcut.id}`} className={classNames("w-8 h-8 flex justify-center items-center overflow-clip shrink-0")}>
|
<Link to={`/shortcut/${shortcut.id}`} className={classNames("w-8 h-8 flex justify-center items-center overflow-clip shrink-0")}>
|
||||||
@ -53,7 +57,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
<div className="w-full flex flex-row justify-start items-center">
|
<div className="w-full flex flex-row justify-start items-center">
|
||||||
<a
|
<a
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"max-w-[calc(100%-36px)] flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow"
|
"max-w-[calc(100%-36px)] flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow dark:hover:bg-zinc-800"
|
||||||
)}
|
)}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={shortcutLink}
|
href={shortcutLink}
|
||||||
@ -64,8 +68,8 @@ const ShortcutView = (props: Props) => {
|
|||||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-400">s/</span>
|
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||||
<span className="truncate">{shortcut.name}</span>
|
<span className="truncate dark:text-gray-400">{shortcut.name}</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -75,14 +79,18 @@ const ShortcutView = (props: Props) => {
|
|||||||
</a>
|
</a>
|
||||||
<Tooltip title="Copy" variant="solid" placement="top" arrow>
|
<Tooltip title="Copy" variant="solid" placement="top" arrow>
|
||||||
<button
|
<button
|
||||||
className="hidden group-hover:block w-6 h-6 cursor-pointer rounded-md text-gray-500 hover:bg-gray-100 hover:shadow"
|
className="hidden group-hover:block w-6 h-6 cursor-pointer rounded-md text-gray-500 hover:bg-gray-100 hover:shadow dark:hover:bg-zinc-800"
|
||||||
onClick={() => handleCopyButtonClick()}
|
onClick={() => handleCopyButtonClick()}
|
||||||
>
|
>
|
||||||
<Icon.Clipboard className="w-4 h-auto mx-auto" />
|
<Icon.Clipboard className="w-4 h-auto mx-auto" />
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<a className="pl-1 pr-4 w-full text-sm truncate text-gray-400 hover:underline" href={shortcut.link} target="_blank">
|
<a
|
||||||
|
className="pl-1 pr-4 w-full text-sm truncate text-gray-400 dark:text-gray-500 hover:underline"
|
||||||
|
href={shortcut.link}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
{shortcut.link}
|
{shortcut.link}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -96,7 +104,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={tag}
|
key={tag}
|
||||||
className="max-w-[8rem] truncate text-gray-400 text-sm font-mono leading-4 cursor-pointer hover:text-gray-600"
|
className="max-w-[8rem] truncate text-gray-400 dark:text-gray-500 text-sm font-mono leading-4 cursor-pointer hover:opacity-80"
|
||||||
onClick={() => viewStore.setFilter({ tag: tag })}
|
onClick={() => viewStore.setFilter({ tag: tag })}
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
@ -107,14 +115,14 @@ const ShortcutView = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-full flex mt-2 gap-2">
|
<div className="w-full flex mt-2 gap-2">
|
||||||
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
||||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm">
|
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||||
<Icon.User className="w-4 h-auto mr-1" />
|
<Icon.User className="w-4 h-auto mr-1" />
|
||||||
<span className="max-w-[4rem] sm:max-w-[6rem] truncate">{shortcut.creator.nickname}</span>
|
<span className="max-w-[4rem] sm:max-w-[6rem] truncate">{shortcut.creator.nickname}</span>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.description`)} variant="solid" placement="top" arrow>
|
<Tooltip title={t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.description`)} variant="solid" placement="top" arrow>
|
||||||
<div
|
<div
|
||||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm"
|
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||||
onClick={() => viewStore.setFilter({ visibility: shortcut.visibility })}
|
onClick={() => viewStore.setFilter({ visibility: shortcut.visibility })}
|
||||||
>
|
>
|
||||||
<VisibilityIcon className="w-4 h-auto mr-1" visibility={shortcut.visibility} />
|
<VisibilityIcon className="w-4 h-auto mr-1" visibility={shortcut.visibility} />
|
||||||
@ -124,7 +132,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
<Tooltip title="View count" variant="solid" placement="top" arrow>
|
<Tooltip title="View count" variant="solid" placement="top" arrow>
|
||||||
<Link
|
<Link
|
||||||
to={`/shortcut/${shortcut.id}#analytics`}
|
to={`/shortcut/${shortcut.id}#analytics`}
|
||||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm"
|
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||||
>
|
>
|
||||||
<Icon.BarChart2 className="w-4 h-auto mr-1" />
|
<Icon.BarChart2 className="w-4 h-auto mr-1" />
|
||||||
{shortcut.view} visits
|
{shortcut.view} visits
|
||||||
|
@ -28,7 +28,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"group w-full px-3 py-2 flex flex-col justify-start items-start border rounded-lg hover:bg-gray-100 hover:shadow"
|
"group w-full px-3 py-2 flex flex-col justify-start items-start border rounded-lg hover:bg-gray-100 hover:shadow dark:border-zinc-800 dark:hover:bg-zinc-800"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
@ -55,8 +55,8 @@ const ShortcutView = (props: Props) => {
|
|||||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-400">s/</span>
|
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||||
<span className="truncate">{shortcut.name}</span>
|
<span className="truncate dark:text-gray-400">{shortcut.name}</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,8 +64,8 @@ const AccessTokenSection = () => {
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="sm:flex sm:items-center">
|
<div className="sm:flex sm:items-center">
|
||||||
<div className="sm:flex-auto">
|
<div className="sm:flex-auto">
|
||||||
<p className="text-base font-semibold leading-6 text-gray-900">Access Tokens</p>
|
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Access Tokens</p>
|
||||||
<p className="mt-2 text-sm text-gray-700">A list of all access tokens for your account.</p>
|
<p className="mt-2 text-sm text-gray-700 dark:text-gray-600">A list of all access tokens for your account.</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
<div className="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
||||||
<Button
|
<Button
|
||||||
@ -82,19 +82,19 @@ const AccessTokenSection = () => {
|
|||||||
<div className="mt-2 flow-root">
|
<div className="mt-2 flow-root">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<div className="inline-block min-w-full py-2 align-middle">
|
<div className="inline-block min-w-full py-2 align-middle">
|
||||||
<table className="min-w-full divide-y divide-gray-300">
|
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-700">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Token
|
Token
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Description
|
Description
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Created At
|
Created At
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Expires At
|
Expires At
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||||
@ -102,16 +102,18 @@ const AccessTokenSection = () => {
|
|||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200">
|
<tbody className="divide-y divide-gray-200 dark:divide-zinc-800">
|
||||||
{userAccessTokens.map((userAccessToken) => (
|
{userAccessTokens.map((userAccessToken) => (
|
||||||
<tr key={userAccessToken.accessToken}>
|
<tr key={userAccessToken.accessToken}>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-900 flex flex-row justify-start items-center gap-x-1">
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-900 flex flex-row justify-start items-center gap-x-1 dark:text-gray-500">
|
||||||
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
||||||
<Button color="neutral" variant="plain" size="sm" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
<Button color="neutral" variant="plain" size="sm" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
||||||
<Icon.Clipboard className="w-4 h-auto text-gray-500" />
|
<Icon.Clipboard className="w-4 h-auto text-gray-500" />
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900">{userAccessToken.description}</td>
|
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-500">
|
||||||
|
{userAccessToken.description}
|
||||||
|
</td>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{userAccessToken.issuedAt?.toLocaleString()}</td>
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{userAccessToken.issuedAt?.toLocaleString()}</td>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||||
{userAccessToken.expiresAt?.toLocaleString() ?? "Never"}
|
{userAccessToken.expiresAt?.toLocaleString() ?? "Never"}
|
||||||
|
@ -15,12 +15,12 @@ const AccountSection: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||||
<p className="text-base font-semibold leading-6 text-gray-900">Account</p>
|
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Account</p>
|
||||||
<p className="flex flex-row justify-start items-center mt-2">
|
<p className="flex flex-row justify-start items-center mt-2 dark:text-gray-400">
|
||||||
<span className="text-xl">{currentUser.nickname}</span>
|
<span className="text-xl">{currentUser.nickname}</span>
|
||||||
{isAdmin && <span className="ml-2 bg-blue-600 text-white px-2 leading-6 text-sm rounded-full">Admin</span>}
|
{isAdmin && <span className="ml-2 bg-blue-600 text-white px-2 leading-6 text-sm rounded-full">Admin</span>}
|
||||||
</p>
|
</p>
|
||||||
<p className="flex flex-row justify-start items-center">
|
<p className="flex flex-row justify-start items-center dark:text-gray-400">
|
||||||
<span className="mr-3 text-gray-500">{t("common.email")}: </span>
|
<span className="mr-3 text-gray-500">{t("common.email")}: </span>
|
||||||
{currentUser.email}
|
{currentUser.email}
|
||||||
</p>
|
</p>
|
||||||
|
@ -43,8 +43,8 @@ const MemberSection = () => {
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="sm:flex sm:items-center">
|
<div className="sm:flex sm:items-center">
|
||||||
<div className="sm:flex-auto">
|
<div className="sm:flex-auto">
|
||||||
<p className="text-base font-semibold leading-6 text-gray-900">Users</p>
|
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Users</p>
|
||||||
<p className="mt-2 text-sm text-gray-700">
|
<p className="mt-2 text-sm text-gray-700 dark:text-gray-600">
|
||||||
A list of all the users in your workspace including their nickname, email and role.
|
A list of all the users in your workspace including their nickname, email and role.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -64,16 +64,16 @@ const MemberSection = () => {
|
|||||||
<div className="mt-2 flow-root">
|
<div className="mt-2 flow-root">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<div className="inline-block min-w-full py-2 align-middle">
|
<div className="inline-block min-w-full py-2 align-middle">
|
||||||
<table className="min-w-full divide-y divide-gray-300">
|
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-700">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Nickname
|
Nickname
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Email
|
Email
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||||
Role
|
Role
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||||
@ -84,7 +84,7 @@ const MemberSection = () => {
|
|||||||
<tbody className="divide-y divide-gray-200">
|
<tbody className="divide-y divide-gray-200">
|
||||||
{userList.map((user) => (
|
{userList.map((user) => (
|
||||||
<tr key={user.email}>
|
<tr key={user.email}>
|
||||||
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900">{user.nickname}</td>
|
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-500">{user.nickname}</td>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{user.email}</td>
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{user.email}</td>
|
||||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{user.role}</td>
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{user.role}</td>
|
||||||
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm">
|
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm">
|
||||||
|
@ -13,31 +13,31 @@ const PreferenceSection: React.FC = () => {
|
|||||||
|
|
||||||
const languageOptions = [
|
const languageOptions = [
|
||||||
{
|
{
|
||||||
value: "LOCALE_EN",
|
value: UserSetting_Locale.LOCALE_EN,
|
||||||
label: "English",
|
label: "English",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "LOCALE_ZH",
|
value: UserSetting_Locale.LOCALE_ZH,
|
||||||
label: "中文",
|
label: "中文",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const colorThemeOptions = [
|
const colorThemeOptions = [
|
||||||
{
|
{
|
||||||
value: "COLOR_THEME_LIGHT",
|
value: UserSetting_ColorTheme.COLOR_THEME_SYSTEM,
|
||||||
|
label: "System",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: UserSetting_ColorTheme.COLOR_THEME_LIGHT,
|
||||||
label: "Light",
|
label: "Light",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "COLOR_THEME_DARK",
|
value: UserSetting_ColorTheme.COLOR_THEME_DARK,
|
||||||
label: "Dark",
|
label: "Dark",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleSelectLanguage = async (locale: UserSetting_Locale) => {
|
const handleSelectLanguage = async (locale: UserSetting_Locale) => {
|
||||||
if (!locale) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await userStore.updateUserSetting(
|
await userStore.updateUserSetting(
|
||||||
{
|
{
|
||||||
...userSetting,
|
...userSetting,
|
||||||
@ -48,10 +48,6 @@ const PreferenceSection: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectColorTheme = async (colorTheme: UserSetting_ColorTheme) => {
|
const handleSelectColorTheme = async (colorTheme: UserSetting_ColorTheme) => {
|
||||||
if (!colorTheme) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await userStore.updateUserSetting(
|
await userStore.updateUserSetting(
|
||||||
{
|
{
|
||||||
...userSetting,
|
...userSetting,
|
||||||
@ -64,10 +60,10 @@ const PreferenceSection: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||||
<p className="text-base font-semibold leading-6 text-gray-900">Preference</p>
|
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Preference</p>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div className="flex flex-row justify-start items-center gap-x-1">
|
<div className="flex flex-row justify-start items-center gap-x-1">
|
||||||
<span>{t("common.language")}</span>
|
<span className="dark:text-gray-400">{t("common.language")}</span>
|
||||||
<BetaBadge />
|
<BetaBadge />
|
||||||
</div>
|
</div>
|
||||||
<Select defaultValue={language} onChange={(_, value) => handleSelectLanguage(value as UserSetting_Locale)}>
|
<Select defaultValue={language} onChange={(_, value) => handleSelectLanguage(value as UserSetting_Locale)}>
|
||||||
@ -82,7 +78,7 @@ const PreferenceSection: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div className="flex flex-row justify-start items-center gap-x-1">
|
<div className="flex flex-row justify-start items-center gap-x-1">
|
||||||
<span>Color Theme</span>
|
<span className="dark:text-gray-400">Color Theme</span>
|
||||||
<BetaBadge />
|
<BetaBadge />
|
||||||
</div>
|
</div>
|
||||||
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
|
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
|
||||||
|
@ -62,9 +62,9 @@ const WorkspaceSection: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
||||||
<p className="text-base font-semibold leading-6 text-gray-900">Workspace settings</p>
|
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Workspace settings</p>
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<p className="mt-2">Custom style</p>
|
<p className="mt-2 dark:text-gray-400">Custom style</p>
|
||||||
<Textarea
|
<Textarea
|
||||||
className="w-full mt-2"
|
className="w-full mt-2"
|
||||||
minRows={2}
|
minRows={2}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
body,
|
body,
|
||||||
html,
|
html,
|
||||||
#root {
|
#root {
|
||||||
@apply text-base w-full h-full dark:bg-zinc-800;
|
@apply text-base w-full h-full dark:bg-zinc-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { createChannel, createClientFactory, FetchTransport } from "nice-grpc-web";
|
import { createChannel, createClientFactory, FetchTransport } from "nice-grpc-web";
|
||||||
import { SubscriptionServiceDefinition } from "./types/proto/api/v2/subscription_service";
|
import { SubscriptionServiceDefinition } from "./types/proto/api/v2/subscription_service";
|
||||||
import { UserServiceDefinition } from "./types/proto/api/v2/user_service";
|
import { UserServiceDefinition } from "./types/proto/api/v2/user_service";
|
||||||
|
import { UserSettingServiceDefinition } from "./types/proto/api/v2/user_setting_service";
|
||||||
import { WorkspaceServiceDefinition } from "./types/proto/api/v2/workspace_service";
|
import { WorkspaceServiceDefinition } from "./types/proto/api/v2/workspace_service";
|
||||||
|
|
||||||
const address = import.meta.env.MODE === "development" ? "http://localhost:8082" : window.location.origin;
|
const address = import.meta.env.MODE === "development" ? "http://localhost:8082" : window.location.origin;
|
||||||
@ -19,3 +20,5 @@ export const subscriptionServiceClient = clientFactory.create(SubscriptionServic
|
|||||||
export const workspaceServiceClient = clientFactory.create(WorkspaceServiceDefinition, channel);
|
export const workspaceServiceClient = clientFactory.create(WorkspaceServiceDefinition, channel);
|
||||||
|
|
||||||
export const userServiceClient = clientFactory.create(UserServiceDefinition, channel);
|
export const userServiceClient = clientFactory.create(UserServiceDefinition, channel);
|
||||||
|
|
||||||
|
export const userSettingServiceClient = clientFactory.create(UserSettingServiceDefinition, channel);
|
||||||
|
@ -3,13 +3,14 @@ import { isEqual } from "lodash-es";
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Outlet, useNavigate } from "react-router-dom";
|
import { Outlet, useNavigate } from "react-router-dom";
|
||||||
|
import { UserSetting_ColorTheme } from "@/types/proto/api/v2/user_setting_service";
|
||||||
import Header from "../components/Header";
|
import Header from "../components/Header";
|
||||||
import useUserStore from "../stores/v1/user";
|
import useUserStore from "../stores/v1/user";
|
||||||
|
|
||||||
const Root: React.FC = () => {
|
const Root: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { i18n } = useTranslation();
|
|
||||||
const { setMode } = useColorScheme();
|
const { setMode } = useColorScheme();
|
||||||
|
const { i18n } = useTranslation();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const currentUser = userStore.getCurrentUser();
|
const currentUser = userStore.getCurrentUser();
|
||||||
const currentUserSetting = userStore.getCurrentUserSetting();
|
const currentUserSetting = userStore.getCurrentUserSetting();
|
||||||
@ -38,19 +39,19 @@ const Root: React.FC = () => {
|
|||||||
i18n.changeLanguage("en");
|
i18n.changeLanguage("en");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEqual(currentUserSetting.colorTheme, "COLOR_THEME_DARK")) {
|
if (currentUserSetting.colorTheme === UserSetting_ColorTheme.COLOR_THEME_LIGHT) {
|
||||||
setMode("dark");
|
|
||||||
document.documentElement.classList.add("dark");
|
|
||||||
} else {
|
|
||||||
setMode("light");
|
setMode("light");
|
||||||
document.documentElement.classList.remove("dark");
|
} else if (currentUserSetting.colorTheme === UserSetting_ColorTheme.COLOR_THEME_DARK) {
|
||||||
|
setMode("dark");
|
||||||
|
} else {
|
||||||
|
setMode("system");
|
||||||
}
|
}
|
||||||
}, [currentUserSetting]);
|
}, [currentUserSetting]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isInitialized && (
|
{isInitialized && (
|
||||||
<div className="w-full h-auto flex flex-col justify-start items-start dark:bg-zinc-800">
|
<div className="w-full h-auto flex flex-col justify-start items-start dark:bg-zinc-900">
|
||||||
<Header />
|
<Header />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,8 +86,8 @@ const ShortcutDetail = () => {
|
|||||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-400">s/</span>
|
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||||
<span className="truncate">{shortcut.name}</span>
|
<span className="truncate dark:text-gray-400">{shortcut.name}</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -98,7 +98,7 @@ const ShortcutDetail = () => {
|
|||||||
<div className="mt-2 w-full flex flex-row justify-normal items-center space-x-2">
|
<div className="mt-2 w-full flex flex-row justify-normal items-center space-x-2">
|
||||||
<Tooltip title="Copy" variant="solid" placement="top" arrow>
|
<Tooltip title="Copy" variant="solid" placement="top" arrow>
|
||||||
<button
|
<button
|
||||||
className="w-8 h-8 cursor-pointer border rounded-full text-gray-500 hover:bg-gray-100 hover:shadow"
|
className="w-8 h-8 cursor-pointer border rounded-full text-gray-500 hover:bg-gray-100 hover:shadow dark:border-zinc-800 dark:hover:bg-zinc-800"
|
||||||
onClick={() => handleCopyButtonClick()}
|
onClick={() => handleCopyButtonClick()}
|
||||||
>
|
>
|
||||||
<Icon.Clipboard className="w-4 h-auto mx-auto" />
|
<Icon.Clipboard className="w-4 h-auto mx-auto" />
|
||||||
@ -106,7 +106,7 @@ const ShortcutDetail = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="QR Code" variant="solid" placement="top" arrow>
|
<Tooltip title="QR Code" variant="solid" placement="top" arrow>
|
||||||
<button
|
<button
|
||||||
className="w-8 h-8 cursor-pointer border rounded-full text-gray-500 hover:bg-gray-100 hover:shadow"
|
className="w-8 h-8 cursor-pointer border rounded-full text-gray-500 hover:bg-gray-100 hover:shadow dark:border-zinc-800 dark:hover:bg-zinc-800"
|
||||||
onClick={() => setShowQRCodeDialog(true)}
|
onClick={() => setShowQRCodeDialog(true)}
|
||||||
>
|
>
|
||||||
<Icon.QrCode className="w-4 h-auto mx-auto" />
|
<Icon.QrCode className="w-4 h-auto mx-auto" />
|
||||||
@ -114,12 +114,12 @@ const ShortcutDetail = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
{havePermission && (
|
{havePermission && (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="w-8 h-8 flex justify-center items-center border cursor-pointer rounded-full hover:bg-gray-100 hover:shadow"
|
className="w-8 h-8 flex justify-center items-center border cursor-pointer rounded-full hover:bg-gray-100 hover:shadow dark:border-zinc-800 dark:hover:bg-zinc-800"
|
||||||
actionsClassName="!w-32 !-right-24"
|
actionsClassName="!w-32 !-right-24 dark:text-gray-500"
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
@ -130,7 +130,7 @@ const ShortcutDetail = () => {
|
|||||||
<Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
|
<Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60 dark:hover:bg-zinc-800"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleDeleteShortcutButtonClick(shortcut);
|
handleDeleteShortcutButtonClick(shortcut);
|
||||||
}}
|
}}
|
||||||
@ -142,32 +142,34 @@ const ShortcutDetail = () => {
|
|||||||
></Dropdown>
|
></Dropdown>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{shortcut.description && <p className="w-full break-all mt-2 text-gray-400 text-sm">{shortcut.description}</p>}
|
{shortcut.description && <p className="w-full break-all mt-2 text-gray-400 text-sm dark:text-gray-500">{shortcut.description}</p>}
|
||||||
<div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2">
|
<div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2">
|
||||||
{shortcut.tags.map((tag) => {
|
{shortcut.tags.map((tag) => {
|
||||||
return (
|
return (
|
||||||
<span key={tag} className="max-w-[8rem] truncate text-gray-400 text font-mono leading-4">
|
<span key={tag} className="max-w-[8rem] truncate text-gray-400 text font-mono leading-4 dark:text-gray-500">
|
||||||
#{tag}
|
#{tag}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm font-mono leading-4 italic">No tags</span>}
|
{shortcut.tags.length === 0 && (
|
||||||
|
<span className="text-gray-400 text-sm font-mono leading-4 italic dark:text-gray-500">No tags</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex mt-4 gap-2">
|
<div className="w-full flex mt-4 gap-2">
|
||||||
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
||||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm">
|
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||||
<Icon.User className="w-4 h-auto mr-1" />
|
<Icon.User className="w-4 h-auto mr-1" />
|
||||||
<span className="max-w-[4rem] sm:max-w-[6rem] truncate">{shortcut.creator.nickname}</span>
|
<span className="max-w-[4rem] sm:max-w-[6rem] truncate">{shortcut.creator.nickname}</span>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.description`)} variant="solid" placement="top" arrow>
|
<Tooltip title={t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.description`)} variant="solid" placement="top" arrow>
|
||||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm">
|
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||||
<VisibilityIcon className="w-4 h-auto mr-1" visibility={shortcut.visibility} />
|
<VisibilityIcon className="w-4 h-auto mr-1" visibility={shortcut.visibility} />
|
||||||
{t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.self`)}
|
{t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.self`)}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="View count" variant="solid" placement="top" arrow>
|
<Tooltip title="View count" variant="solid" placement="top" arrow>
|
||||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm">
|
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||||
<Icon.BarChart2 className="w-4 h-auto mr-1" />
|
<Icon.BarChart2 className="w-4 h-auto mr-1" />
|
||||||
{shortcut.view} visits
|
{shortcut.view} visits
|
||||||
</div>
|
</div>
|
||||||
@ -175,7 +177,7 @@ const ShortcutDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full flex flex-col mt-8">
|
<div className="w-full flex flex-col mt-8">
|
||||||
<h3 id="analytics" className="pl-1 font-medium text-lg flex flex-row justify-start items-center">
|
<h3 id="analytics" className="pl-1 font-medium text-lg flex flex-row justify-start items-center dark:text-gray-400">
|
||||||
<Icon.BarChart2 className="w-6 h-auto mr-1" />
|
<Icon.BarChart2 className="w-6 h-auto mr-1" />
|
||||||
{t("analytics.self")}
|
{t("analytics.self")}
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -68,12 +68,12 @@ const SignIn: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-center items-center w-full h-auto mt-12 sm:mt-24 bg-white">
|
<div className="flex flex-row justify-center items-center w-full h-auto mt-12 sm:mt-24 bg-white dark:bg-zinc-900">
|
||||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
||||||
<img src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
<img src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
||||||
<span className="text-3xl opacity-80">Slash</span>
|
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}>
|
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}>
|
||||||
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
||||||
@ -107,7 +107,7 @@ const SignIn: React.FC = () => {
|
|||||||
</form>
|
</form>
|
||||||
{enableSignup && (
|
{enableSignup && (
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span>{"Don't have an account yet?"}</span>
|
<span className="dark:text-gray-500">{"Don't have an account yet?"}</span>
|
||||||
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
||||||
Sign up
|
Sign up
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -75,14 +75,14 @@ const SignUp: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-center items-center w-full h-auto mt-12 sm:mt-24 bg-white">
|
<div className="flex flex-row justify-center items-center w-full h-auto mt-12 sm:mt-24 bg-white dark:bg-zinc-900">
|
||||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
||||||
<img src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
<img src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
||||||
<span className="text-3xl opacity-80">Slash</span>
|
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-2xl mt-6">Create your account</p>
|
<p className="w-full text-2xl mt-6 dark:text-gray-500">Create your account</p>
|
||||||
<form className="w-full mt-4" onSubmit={handleSignupBtnClick}>
|
<form className="w-full mt-4" onSubmit={handleSignupBtnClick}>
|
||||||
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
||||||
<div className="w-full flex flex-col mb-2">
|
<div className="w-full flex flex-col mb-2">
|
||||||
@ -118,7 +118,7 @@ const SignUp: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span>{"Already has an account?"}</span>
|
<span className="dark:text-gray-500">{"Already has an account?"}</span>
|
||||||
<Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
<Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
||||||
Sign in
|
Sign in
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import axios from "axios";
|
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { GetUserSettingResponse, UpdateUserSettingResponse, UserSetting } from "@/types/proto/api/v2/user_setting_service";
|
import { userSettingServiceClient } from "@/grpcweb";
|
||||||
|
import { UserSetting } from "@/types/proto/api/v2/user_setting_service";
|
||||||
import * as api from "../../helpers/api";
|
import * as api from "../../helpers/api";
|
||||||
|
|
||||||
const convertResponseModelUser = (user: User): User => {
|
const convertResponseModelUser = (user: User): User => {
|
||||||
@ -95,12 +95,11 @@ const useUserStore = create<UserState>()((set, get) => ({
|
|||||||
return userMap[currentUserId as UserId];
|
return userMap[currentUserId as UserId];
|
||||||
},
|
},
|
||||||
fetchUserSetting: async (userId: UserId) => {
|
fetchUserSetting: async (userId: UserId) => {
|
||||||
const {
|
const userSetting = (
|
||||||
data: { userSetting },
|
await userSettingServiceClient.getUserSetting({
|
||||||
} = await axios.get<GetUserSettingResponse>(`api/v2/users/${userId}/settings`);
|
id: userId,
|
||||||
if (!userSetting) {
|
})
|
||||||
throw new Error(`User setting not found for user ${userId}`);
|
).userSetting as UserSetting;
|
||||||
}
|
|
||||||
const userSettingMap = get().userSettingMapById;
|
const userSettingMap = get().userSettingMapById;
|
||||||
userSettingMap[userId] = userSetting;
|
userSettingMap[userId] = userSetting;
|
||||||
set(userSettingMap);
|
set(userSettingMap);
|
||||||
@ -108,16 +107,13 @@ const useUserStore = create<UserState>()((set, get) => ({
|
|||||||
},
|
},
|
||||||
updateUserSetting: async (userSetting: UserSetting, updateMask: string[]) => {
|
updateUserSetting: async (userSetting: UserSetting, updateMask: string[]) => {
|
||||||
const userId = userSetting.id;
|
const userId = userSetting.id;
|
||||||
const {
|
const updatedUserSetting = (
|
||||||
data: { userSetting: updatedUserSetting },
|
await userSettingServiceClient.updateUserSetting({
|
||||||
} = await axios.post<UpdateUserSettingResponse>(`api/v2/users/${userId}/settings`, {
|
|
||||||
id: userId,
|
id: userId,
|
||||||
userSetting,
|
userSetting,
|
||||||
updateMask,
|
updateMask,
|
||||||
});
|
})
|
||||||
if (!updatedUserSetting) {
|
).userSetting as UserSetting;
|
||||||
throw new Error(`User setting not found for user ${userId}`);
|
|
||||||
}
|
|
||||||
const userSettingMap = get().userSettingMapById;
|
const userSettingMap = get().userSettingMapById;
|
||||||
userSettingMap[userId] = updatedUserSetting;
|
userSettingMap[userId] = updatedUserSetting;
|
||||||
set(userSettingMap);
|
set(userSettingMap);
|
||||||
|
@ -37,8 +37,9 @@ message UserSetting {
|
|||||||
|
|
||||||
enum ColorTheme {
|
enum ColorTheme {
|
||||||
COLOR_THEME_UNSPECIFIED = 0;
|
COLOR_THEME_UNSPECIFIED = 0;
|
||||||
COLOR_THEME_LIGHT = 1;
|
COLOR_THEME_SYSTEM = 1;
|
||||||
COLOR_THEME_DARK = 2;
|
COLOR_THEME_LIGHT = 2;
|
||||||
|
COLOR_THEME_DARK = 3;
|
||||||
}
|
}
|
||||||
// color_theme is the user color theme.
|
// color_theme is the user color theme.
|
||||||
ColorTheme color_theme = 3;
|
ColorTheme color_theme = 3;
|
||||||
|
@ -835,8 +835,9 @@
|
|||||||
| Name | Number | Description |
|
| Name | Number | Description |
|
||||||
| ---- | ------ | ----------- |
|
| ---- | ------ | ----------- |
|
||||||
| COLOR_THEME_UNSPECIFIED | 0 | |
|
| COLOR_THEME_UNSPECIFIED | 0 | |
|
||||||
| COLOR_THEME_LIGHT | 1 | |
|
| COLOR_THEME_SYSTEM | 1 | |
|
||||||
| COLOR_THEME_DARK | 2 | |
|
| COLOR_THEME_LIGHT | 2 | |
|
||||||
|
| COLOR_THEME_DARK | 3 | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,21 +74,24 @@ type UserSetting_ColorTheme int32
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
UserSetting_COLOR_THEME_UNSPECIFIED UserSetting_ColorTheme = 0
|
UserSetting_COLOR_THEME_UNSPECIFIED UserSetting_ColorTheme = 0
|
||||||
UserSetting_COLOR_THEME_LIGHT UserSetting_ColorTheme = 1
|
UserSetting_COLOR_THEME_SYSTEM UserSetting_ColorTheme = 1
|
||||||
UserSetting_COLOR_THEME_DARK UserSetting_ColorTheme = 2
|
UserSetting_COLOR_THEME_LIGHT UserSetting_ColorTheme = 2
|
||||||
|
UserSetting_COLOR_THEME_DARK UserSetting_ColorTheme = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for UserSetting_ColorTheme.
|
// Enum value maps for UserSetting_ColorTheme.
|
||||||
var (
|
var (
|
||||||
UserSetting_ColorTheme_name = map[int32]string{
|
UserSetting_ColorTheme_name = map[int32]string{
|
||||||
0: "COLOR_THEME_UNSPECIFIED",
|
0: "COLOR_THEME_UNSPECIFIED",
|
||||||
1: "COLOR_THEME_LIGHT",
|
1: "COLOR_THEME_SYSTEM",
|
||||||
2: "COLOR_THEME_DARK",
|
2: "COLOR_THEME_LIGHT",
|
||||||
|
3: "COLOR_THEME_DARK",
|
||||||
}
|
}
|
||||||
UserSetting_ColorTheme_value = map[string]int32{
|
UserSetting_ColorTheme_value = map[string]int32{
|
||||||
"COLOR_THEME_UNSPECIFIED": 0,
|
"COLOR_THEME_UNSPECIFIED": 0,
|
||||||
"COLOR_THEME_LIGHT": 1,
|
"COLOR_THEME_SYSTEM": 1,
|
||||||
"COLOR_THEME_DARK": 2,
|
"COLOR_THEME_LIGHT": 2,
|
||||||
|
"COLOR_THEME_DARK": 3,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -402,7 +405,7 @@ var file_api_v2_user_setting_service_proto_rawDesc = []byte{
|
|||||||
0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e,
|
0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e,
|
||||||
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||||
0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65,
|
0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65,
|
||||||
0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65,
|
0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xce, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65,
|
||||||
0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x61,
|
0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x61,
|
||||||
0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||||
@ -416,66 +419,67 @@ var file_api_v2_user_setting_service_proto_rawDesc = []byte{
|
|||||||
0x61, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x4e,
|
0x61, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x4e,
|
||||||
0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c,
|
0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c,
|
||||||
0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x4f,
|
0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x4f,
|
||||||
0x43, 0x41, 0x4c, 0x45, 0x5f, 0x5a, 0x48, 0x10, 0x02, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6c,
|
0x43, 0x41, 0x4c, 0x45, 0x5f, 0x5a, 0x48, 0x10, 0x02, 0x22, 0x6e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c,
|
||||||
0x6f, 0x72, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4c, 0x4f, 0x52,
|
0x6f, 0x72, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4c, 0x4f, 0x52,
|
||||||
0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48,
|
0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48,
|
||||||
0x45, 0x4d, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43,
|
0x45, 0x4d, 0x45, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11,
|
||||||
0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x44, 0x41, 0x52, 0x4b, 0x10,
|
0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48,
|
||||||
0x02, 0x22, 0x27, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74,
|
0x54, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45,
|
||||||
0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
0x4d, 0x45, 0x5f, 0x44, 0x41, 0x52, 0x4b, 0x10, 0x03, 0x22, 0x27, 0x0a, 0x15, 0x47, 0x65, 0x74,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x56, 0x0a, 0x16, 0x47, 0x65,
|
0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70,
|
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74,
|
0x69, 0x64, 0x22, 0x56, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74,
|
||||||
0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x61,
|
0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c,
|
||||||
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65,
|
0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69,
|
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||||
0x6e, 0x67, 0x22, 0x89, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
|
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x75,
|
||||||
0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x89, 0x01, 0x0a, 0x18, 0x55,
|
||||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
|
0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
||||||
0x3c, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18,
|
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70,
|
0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f,
|
||||||
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
|
||||||
0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a,
|
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65,
|
||||||
0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03,
|
0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x53, 0x65,
|
||||||
0x28, 0x09, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x59,
|
0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
|
||||||
0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74,
|
0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61,
|
||||||
0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x75,
|
0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x59, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||||
0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74,
|
||||||
0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x75, 0x73,
|
0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6c, 0x61, 0x73,
|
||||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x32, 0xb0, 0x02, 0x0a, 0x12, 0x55, 0x73,
|
0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74,
|
||||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||||
0x12, 0x85, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74,
|
0x67, 0x32, 0xb0, 0x02, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||||
0x69, 0x6e, 0x67, 0x12, 0x23, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74,
|
||||||
0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x2e, 0x73, 0x6c,
|
||||||
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73,
|
||||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53,
|
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28,
|
0x1a, 0x24, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||||
0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70,
|
0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65,
|
||||||
0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f,
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4,
|
||||||
0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64,
|
0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65,
|
||||||
0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x26,
|
0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
|
||||||
|
0x12, 0x91, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53,
|
||||||
|
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
|
||||||
|
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
|
||||||
|
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27,
|
||||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
|
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
|
||||||
0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52,
|
0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
|
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3,
|
||||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
|
0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
|
||||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x65, 0x74, 0x74,
|
||||||
0x2b, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22,
|
0x69, 0x6e, 0x67, 0x73, 0x42, 0xae, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61,
|
||||||
0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b,
|
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x17, 0x55, 0x73, 0x65, 0x72, 0x53,
|
||||||
0x69, 0x64, 0x7d, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0xae, 0x01, 0x0a,
|
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f,
|
||||||
0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||||
0x32, 0x42, 0x17, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65,
|
0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70,
|
||||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69,
|
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b,
|
||||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b,
|
0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c,
|
||||||
0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e,
|
0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61,
|
||||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03,
|
0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73,
|
||||||
0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e,
|
0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
|
||||||
0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56,
|
0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70,
|
||||||
0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32,
|
0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53,
|
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70,
|
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -234,8 +234,9 @@
|
|||||||
| Name | Number | Description |
|
| Name | Number | Description |
|
||||||
| ---- | ------ | ----------- |
|
| ---- | ------ | ----------- |
|
||||||
| COLOR_THEME_USER_SETTING_UNSPECIFIED | 0 | |
|
| COLOR_THEME_USER_SETTING_UNSPECIFIED | 0 | |
|
||||||
| COLOR_THEME_USER_SETTING_LIGHT | 1 | |
|
| COLOR_THEME_USER_SETTING_SYSTEM | 1 | |
|
||||||
| COLOR_THEME_USER_SETTING_DARK | 2 | |
|
| COLOR_THEME_USER_SETTING_LIGHT | 2 | |
|
||||||
|
| COLOR_THEME_USER_SETTING_DARK | 3 | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,21 +128,24 @@ type ColorThemeUserSetting int32
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_UNSPECIFIED ColorThemeUserSetting = 0
|
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_UNSPECIFIED ColorThemeUserSetting = 0
|
||||||
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT ColorThemeUserSetting = 1
|
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_SYSTEM ColorThemeUserSetting = 1
|
||||||
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK ColorThemeUserSetting = 2
|
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT ColorThemeUserSetting = 2
|
||||||
|
ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK ColorThemeUserSetting = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for ColorThemeUserSetting.
|
// Enum value maps for ColorThemeUserSetting.
|
||||||
var (
|
var (
|
||||||
ColorThemeUserSetting_name = map[int32]string{
|
ColorThemeUserSetting_name = map[int32]string{
|
||||||
0: "COLOR_THEME_USER_SETTING_UNSPECIFIED",
|
0: "COLOR_THEME_USER_SETTING_UNSPECIFIED",
|
||||||
1: "COLOR_THEME_USER_SETTING_LIGHT",
|
1: "COLOR_THEME_USER_SETTING_SYSTEM",
|
||||||
2: "COLOR_THEME_USER_SETTING_DARK",
|
2: "COLOR_THEME_USER_SETTING_LIGHT",
|
||||||
|
3: "COLOR_THEME_USER_SETTING_DARK",
|
||||||
}
|
}
|
||||||
ColorThemeUserSetting_value = map[string]int32{
|
ColorThemeUserSetting_value = map[string]int32{
|
||||||
"COLOR_THEME_USER_SETTING_UNSPECIFIED": 0,
|
"COLOR_THEME_USER_SETTING_UNSPECIFIED": 0,
|
||||||
"COLOR_THEME_USER_SETTING_LIGHT": 1,
|
"COLOR_THEME_USER_SETTING_SYSTEM": 1,
|
||||||
"COLOR_THEME_USER_SETTING_DARK": 2,
|
"COLOR_THEME_USER_SETTING_LIGHT": 2,
|
||||||
|
"COLOR_THEME_USER_SETTING_DARK": 3,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -441,26 +444,28 @@ var file_store_user_setting_proto_rawDesc = []byte{
|
|||||||
0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x53,
|
0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x53,
|
||||||
0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x10, 0x01, 0x12,
|
0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x10, 0x01, 0x12,
|
||||||
0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53,
|
0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53,
|
||||||
0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x5a, 0x48, 0x10, 0x02, 0x2a, 0x88, 0x01, 0x0a, 0x15,
|
0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x5a, 0x48, 0x10, 0x02, 0x2a, 0xad, 0x01, 0x0a, 0x15,
|
||||||
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65,
|
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65,
|
||||||
0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x24, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54,
|
0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x24, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54,
|
||||||
0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e,
|
0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e,
|
||||||
0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
|
0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
|
||||||
0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55,
|
0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55,
|
||||||
0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x49, 0x47, 0x48,
|
0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x59, 0x53, 0x54,
|
||||||
0x54, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48, 0x45,
|
0x45, 0x4d, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x5f, 0x54, 0x48,
|
||||||
0x4d, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f,
|
0x45, 0x4d, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
||||||
0x44, 0x41, 0x52, 0x4b, 0x10, 0x02, 0x42, 0x9a, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73,
|
0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4c, 0x4f,
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72,
|
0x52, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54,
|
||||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28,
|
0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, 0x52, 0x4b, 0x10, 0x03, 0x42, 0x9a, 0x01, 0x0a, 0x0f,
|
||||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61,
|
0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42,
|
||||||
0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
|
0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74,
|
||||||
0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53, 0x58, 0xaa, 0x02,
|
0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||||
0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x53,
|
0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72,
|
||||||
0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x53, 0x6c, 0x61,
|
0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03,
|
||||||
0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
|
0x53, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72,
|
||||||
0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x53, 0x74,
|
0x65, 0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2,
|
||||||
0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x02, 0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50,
|
||||||
|
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73,
|
||||||
|
0x68, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -47,6 +47,7 @@ enum LocaleUserSetting {
|
|||||||
|
|
||||||
enum ColorThemeUserSetting {
|
enum ColorThemeUserSetting {
|
||||||
COLOR_THEME_USER_SETTING_UNSPECIFIED = 0;
|
COLOR_THEME_USER_SETTING_UNSPECIFIED = 0;
|
||||||
COLOR_THEME_USER_SETTING_LIGHT = 1;
|
COLOR_THEME_USER_SETTING_SYSTEM = 1;
|
||||||
COLOR_THEME_USER_SETTING_DARK = 2;
|
COLOR_THEME_USER_SETTING_LIGHT = 2;
|
||||||
|
COLOR_THEME_USER_SETTING_DARK = 3;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ func (s *LicenseService) LoadSubscription(ctx context.Context) (*apiv2pb.Subscri
|
|||||||
return nil, errors.Wrap(err, "failed to get workspace setting")
|
return nil, errors.Wrap(err, "failed to get workspace setting")
|
||||||
}
|
}
|
||||||
subscription := &apiv2pb.Subscription{
|
subscription := &apiv2pb.Subscription{
|
||||||
Plan: apiv2pb.PlanType_FREE,
|
// NOTE: Default to pro plan for now.
|
||||||
|
Plan: apiv2pb.PlanType_PRO,
|
||||||
}
|
}
|
||||||
licenseKey := ""
|
licenseKey := ""
|
||||||
if workspaceSetting != nil {
|
if workspaceSetting != nil {
|
||||||
|
@ -186,6 +186,8 @@ func convertUserSettingLocaleFromString(s string) storepb.LocaleUserSetting {
|
|||||||
|
|
||||||
func convertUserSettingColorThemeFromString(s string) storepb.ColorThemeUserSetting {
|
func convertUserSettingColorThemeFromString(s string) storepb.ColorThemeUserSetting {
|
||||||
switch s {
|
switch s {
|
||||||
|
case "COLOR_THEME_USER_SETTING_SYSTEM":
|
||||||
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_SYSTEM
|
||||||
case "COLOR_THEME_USER_SETTING_LIGHT":
|
case "COLOR_THEME_USER_SETTING_LIGHT":
|
||||||
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT
|
||||||
case "COLOR_THEME_USER_SETTING_DARK":
|
case "COLOR_THEME_USER_SETTING_DARK":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user