Skip to content

Commit

Permalink
add more settings inf frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
0-don committed Dec 22, 2024
1 parent 0a77026 commit 3018b9b
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 37 deletions.
24 changes: 21 additions & 3 deletions src-tauri/common/src/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ pub fn get_system_language() -> Language {
if let Ok(lang) = std::env::var("LANG") {
let lang = lang.to_lowercase();
match &lang[..2] {
s if s == Language::German.to_string() => Language::German,
s if s == Language::Mandarin.to_string() => Language::Mandarin,
s if s == Language::Hindi.to_string() => Language::Hindi,
s if s == Language::Spanish.to_string() => Language::Spanish,
s if s == Language::French.to_string() => Language::French,
s if s == Language::Arabic.to_string() => Language::Arabic,
s if s == Language::Bengali.to_string() => Language::Bengali,
s if s == Language::Portuguese.to_string() => Language::Portuguese,
s if s == Language::Russian.to_string() => Language::Russian,
s if s == Language::Urdu.to_string() => Language::Urdu,
_ => Language::English,
}
} else {
Expand All @@ -24,9 +30,15 @@ pub fn get_system_language() -> Language {
if let Ok(lang) = std::str::from_utf8(&result.stdout) {
let lang = lang.trim().to_lowercase();
match lang.as_str() {
s if s == Language::German.to_string() => Language::German,
s if s == Language::Mandarin.to_string() => Language::Mandarin,
s if s == Language::Hindi.to_string() => Language::Hindi,
s if s == Language::Spanish.to_string() => Language::Spanish,
s if s == Language::French.to_string() => Language::French,
s if s == Language::Arabic.to_string() => Language::Arabic,
s if s == Language::Bengali.to_string() => Language::Bengali,
s if s == Language::Portuguese.to_string() => Language::Portuguese,
s if s == Language::Russian.to_string() => Language::Russian,
s if s == Language::Urdu.to_string() => Language::Urdu,
_ => Language::English,
}
} else {
Expand All @@ -46,9 +58,15 @@ pub fn get_system_language() -> Language {
if let Ok(lang) = std::str::from_utf8(&result.stdout) {
let lang = lang.to_lowercase();
match &lang[..2] {
s if s == Language::German.to_string() => Language::German,
s if s == Language::Mandarin.to_string() => Language::Mandarin,
s if s == Language::Hindi.to_string() => Language::Hindi,
s if s == Language::Spanish.to_string() => Language::Spanish,
s if s == Language::French.to_string() => Language::French,
s if s == Language::Arabic.to_string() => Language::Arabic,
s if s == Language::Bengali.to_string() => Language::Bengali,
s if s == Language::Portuguese.to_string() => Language::Portuguese,
s if s == Language::Russian.to_string() => Language::Russian,
s if s == Language::Urdu.to_string() => Language::Urdu,
_ => Language::English,
}
} else {
Expand Down
53 changes: 51 additions & 2 deletions src-tauri/common/src/types/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,43 @@ use sea_orm::{sea_query, EnumIter};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value as JsonValue};

#[derive(Iden, EnumIter, PartialEq, Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum ClippyPosition {
#[iden = "mouse_pointer"]
MousePointer,
#[iden = "top_left"]
TopLeft,
#[iden = "top_right"]
TopRight,
#[iden = "bottom_left"]
BottomLeft,
#[iden = "bottom_right"]
BottomRight,
#[iden = "top_center"]
TopCenter,
#[iden = "bottom_center"]
BottomCenter,
#[iden = "left_center"]
LeftCenter,
#[iden = "right_center"]
RightCenter,
#[iden = "center"]
Center,
#[iden = "tray_left"]
TrayLeft,
#[iden = "tray_bottom_left"]
TrayBottomLeft,
#[iden = "tray_right"]
TrayRight,
#[iden = "tray_bottom_right"]
TrayBottomRight,
#[iden = "tray_center"]
TrayCenter,
#[iden = "tray_bottom_center"]
TrayBottomCenter,
}

#[derive(Iden, EnumIter, PartialEq, Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum FolderLocation {
Expand All @@ -17,12 +54,24 @@ pub enum FolderLocation {
pub enum Language {
#[iden = "en"]
English,
#[iden = "zh"]
Mandarin,
#[iden = "hi"]
Hindi,
#[iden = "es"]
Spanish,
#[iden = "fr"]
French,
#[iden = "de"]
German,
#[iden = "ar"]
Arabic,
#[iden = "bn"]
Bengali,
#[iden = "pt"]
Portuguese,
#[iden = "ru"]
Russian,
#[iden = "ur"]
Urdu,
}

#[derive(Iden, EnumIter, PartialEq, Serialize, Deserialize, Debug, Clone)]
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/entity/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Model {
pub synchronize: bool,
pub dark_mode: bool,
pub display_scale: f32,
pub position: String,
pub max_file_size: i32,
pub max_image_size: i32,
pub max_text_size: i32,
Expand All @@ -35,6 +36,7 @@ pub enum Column {
Synchronize,
DarkMode,
DisplayScale,
Position,
MaxFileSize,
MaxImageSize,
MaxTextSize,
Expand Down Expand Up @@ -67,6 +69,7 @@ impl ColumnTrait for Column {
Self::Synchronize => ColumnType::Boolean.def(),
Self::DarkMode => ColumnType::Boolean.def(),
Self::DisplayScale => ColumnType::Float.def(),
Self::Position => ColumnType::String(StringLen::None).def(),
Self::MaxFileSize => ColumnType::Integer.def(),
Self::MaxImageSize => ColumnType::Integer.def(),
Self::MaxTextSize => ColumnType::Integer.def(),
Expand Down
23 changes: 22 additions & 1 deletion src-tauri/migration/src/m000007_create_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use common::{
MAX_TEXT_SIZE, MAX_TEXT_SIZE_MIN,
},
language::get_system_language,
types::enums::{ClippyPosition, Language},
};
use sea_orm::Iterable;
use sea_orm_migration::{
prelude::*,
schema::{boolean, float, integer, pk_auto, string},
Expand All @@ -22,6 +24,7 @@ enum Settings {
Synchronize,
DarkMode,
DisplayScale,
Position,
//
MaxFileSize,
MaxImageSize,
Expand All @@ -45,7 +48,14 @@ impl MigrationTrait for Migration {
.col(
string(Settings::Language)
.string_len(2)
.default(get_system_language().to_string()),
.default(get_system_language().to_string())
.check(
Expr::col(Settings::Language).is_in(
Language::iter()
.map(|x| x.to_string())
.collect::<Vec<String>>(),
),
),
)
.col(boolean(Settings::Startup).default(true))
.col(boolean(Settings::Synchronize).default(false))
Expand All @@ -62,6 +72,17 @@ impl MigrationTrait for Migration {
),
),
)
.col(
string(Settings::Position)
.default(ClippyPosition::MousePointer.to_string())
.check(
Expr::col(Settings::Position).is_in(
ClippyPosition::iter()
.map(|x| x.to_string())
.collect::<Vec<String>>(),
),
),
)
// 10MB default, 0 min, 100MB max
.col(
integer(Settings::MaxFileSize).default(MAX_FILE_SIZE).check(
Expand Down
10 changes: 10 additions & 0 deletions src-tauri/src/service/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::env;
use std::process::Command;
use tauri::{Emitter, LogicalSize, Manager, WebviewUrl};
use tauri::{PhysicalPosition, WebviewWindowBuilder};
use tauri_plugin_positioner::{Position, WindowExt};

/// App
pub fn init_window() {
Expand Down Expand Up @@ -56,6 +57,14 @@ pub fn toggle_main_window() {
.expect("Failed to emit set global hotkey event");
} else {
position_window_near_cursor();
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
let size = calculate_logical_size(MAIN_WINDOW_X, MAIN_WINDOW_Y).await;
get_main_window()
.set_size(size)
.expect("Failed to set window size");
})
});
get_main_window()
.emit(
ListenEvent::ChangeTab.to_string().as_str(),
Expand Down Expand Up @@ -145,6 +154,7 @@ pub fn position_window_near_cursor() {
window
.set_position(final_pos)
.expect("Failed to set window position");
let _ = window.as_ref().window().move_window(Position::TopRight);
}
}

Expand Down
43 changes: 29 additions & 14 deletions src/components/elements/input.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
import { Component } from "solid-js";
import { Component, JSX, createSignal } from "solid-js";

interface InputProps {
type InputProps = JSX.InputHTMLAttributes<HTMLInputElement> & {
debounce?: number;
className?: string;
value: string;
onChange: (value: string) => void;
placeholder?: string;
type?: string;
}
};

export const Input: Component<InputProps> = ({ className, debounce = 0, onInput, value: initialValue = "", ...props }) => {
let timeoutId: number;
const [value, setValue] = createSignal(initialValue as string);

const handleInput: JSX.EventHandler<HTMLInputElement, InputEvent> = (e) => {
const target = e.currentTarget;
setValue(target.value);

if (debounce > 0) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
// @ts-ignore
onInput?.(e);
}, debounce);
} else {
// @ts-ignore
onInput?.(e);
}
};

export const Input: Component<InputProps> = (props) => {
return (
<div
class={`${
props.className ? props.className : ""
className ? className : ""
} group flex items-center justify-between rounded-md border border-gray-300 p-1 px-1.5 text-sm focus-within:border-indigo-500 dark:border-dark-light dark:bg-dark-light`}
>
<input
type={props.type || "text"}
value={props.value}
onChange={(e) => props.onChange(e.currentTarget.value)}
placeholder={props.placeholder}
{...props}
onInput={handleInput}
value={value()}
class="w-full appearance-none bg-transparent text-sm focus:outline-none focus:ring-0 dark:text-white"
/>
</div>
);
};
};
59 changes: 43 additions & 16 deletions src/components/pages/settings/settings-general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { HiSolidCog8Tooth } from "solid-icons/hi";
import { IoLanguageOutline } from "solid-icons/io";
import { RiDeviceKeyboardFill } from "solid-icons/ri";
import { VsRocket } from "solid-icons/vs";
import { Component, Show } from "solid-js";
import { Component, createEffect, Show } from "solid-js";
import { HotkeyStore } from "../../../store/hotkey-store";
import { SettingsStore } from "../../../store/settings-store";
import { HotkeyEvent, Language } from "../../../types/enums";
import { ClippyPosition, HotkeyEvent, Language, WebWindow } from "../../../types/enums";
import { InvokeCommand } from "../../../types/tauri-invoke";
import { invokeCommand } from "../../../utils/tauri";
import { Dropdown } from "../../elements/dropdown";
import { Input } from "../../elements/input";
import { TextBlock } from "../../elements/text-block";
Expand All @@ -18,6 +20,9 @@ import { Shortcut } from "../../utils/shortcut";
interface SettingsGeneralProps {}

export const SettingsGeneral: Component<SettingsGeneralProps> = ({}) => {
createEffect(() => {
console.log("settings", SettingsStore.settings());
}, []);
return (
<Show when={SettingsStore.settings()}>
<TextBlock Icon={RiDeviceKeyboardFill} title="Keyboard shortcut">
Expand All @@ -44,15 +49,24 @@ export const SettingsGeneral: Component<SettingsGeneralProps> = ({}) => {
</div>
</div>

<div class="flex items-center justify-between space-x-2 px-5 pb-5">
<div class="flex items-center space-x-2 truncate">
<FiMoon class="dark:text-white" />
<h6 class="text-sm">Switch Theme</h6>
</div>
<div>
<DarkMode />
</div>
</div>

<div class="flex items-center justify-between space-x-2 px-5 pb-5">
<div class="flex items-center space-x-2 truncate">
<IoLanguageOutline />
<h6 class="text-sm">Change language</h6>
</div>

<Dropdown
className="w-16"
items={Object.entries(Language).map(([key, value]) => ({ value: value, label: key }))}
items={Object.entries(ClippyPosition).map(([key, value]) => ({ value: value, label: key }))}
value={SettingsStore.settings()!.language}
onChange={(language) => {
SettingsStore.updateSettings({ ...SettingsStore.settings()!, language: language as Language });
Expand All @@ -62,27 +76,40 @@ export const SettingsGeneral: Component<SettingsGeneralProps> = ({}) => {

<div class="flex items-center justify-between space-x-2 px-5 pb-5">
<div class="flex items-center space-x-2 truncate">
<CgDisplayFlex />
<h6 class="text-sm">Display Scale</h6>
<IoLanguageOutline />
<h6 class="text-sm">Change language</h6>
</div>

<Input
className="w-16"
value={SettingsStore.settings()!.display_scale.toString()}
onChange={(display_scale) => {
SettingsStore.updateSettings({ ...SettingsStore.settings()!, display_scale: parseInt(display_scale) });
<Dropdown
items={Object.entries(Language).map(([key, value]) => ({ value: value, label: key }))}
value={SettingsStore.settings()!.language}
onChange={(language) => {
SettingsStore.updateSettings({ ...SettingsStore.settings()!, language: language as Language });
}}
/>
</div>

<div class="flex items-center justify-between space-x-2 px-5 pb-5">
<div class="flex items-center space-x-2 truncate">
<FiMoon class="dark:text-white" />
<h6 class="text-sm">Switch Theme.</h6>
</div>
<div>
<DarkMode />
<CgDisplayFlex />
<h6 class="text-sm">Display Scale</h6>
</div>

<Input
type="number"
step="0.01"
min={0.5}
max={2}
value={SettingsStore.settings()!.display_scale}
debounce={1000}
onInput={async (e) => {
SettingsStore.updateSettings({
...SettingsStore.settings()!,
display_scale: Number(parseFloat(e.target.value).toFixed(2)),
});
await invokeCommand(InvokeCommand.OpenNewWindow, { windowName: WebWindow.Settings });
}}
/>
</div>
</TextBlock>
</Show>
Expand Down
Loading

0 comments on commit 3018b9b

Please sign in to comment.