-
Compact mode
+
div:first-child {
+ width: 292px;
+}
+
.settingContent .form {
display: flex;
flex-direction: row;
@@ -86,30 +92,37 @@ Modal
cursor: pointer;
transition: opacity 0.2s linear;
}
+
.settingContent button:hover {
opacity: 0.9;
}
+
.rssButton {
background-color: #ee802f;
color: white;
}
+
.rssButton:hover {
opacity: 0.9;
}
+
.settingContent {
width: 100%;
flex: 1;
}
+
.settingHint {
font-size: 12px;
margin-top: 12px;
}
+
.settingHint a {
text-decoration: underline;
cursor: pointer;
font-weight: 500;
color: var(--primary-text-color);
}
+
.modalHeader {
display: flex;
flex-direction: row;
@@ -122,6 +135,7 @@ Modal
padding: 0;
color: var(--primary-text-color);
}
+
.modalCloseBtn {
align-items: center;
background-color: transparent;
@@ -137,10 +151,58 @@ Modal
text-align: center;
width: 40px;
}
+
.modalCloseBtn:hover {
opacity: 0.7;
}
+.timeInputs {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 8px;
+}
+
+.timeInput {
+ width: 40px;
+ height: 28px;
+ padding: 2px 4px;
+ border: 1px solid var(--settings-input-border-color);
+ border-radius: 4px;
+ background: var(--settings-input-background-color);
+ color: var(--settings-input-text-color);
+ font-size: 13px;
+ text-align: center;
+}
+
+.timeInput:focus {
+ outline: none;
+ border-color: var(--settings-input-border-focus-color);
+}
+
+/* Style the spinners */
+.timeInput::-webkit-inner-spin-button {
+ opacity: 1;
+ background: transparent;
+ cursor: pointer;
+ height: 24px;
+}
+
+.timeInput::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.timeInput[type=number] {
+ -moz-appearance: textfield;
+ appearance: textfield;
+}
+
+.timeInputs span {
+ color: var(--secondary-text-color);
+ font-size: 13px;
+}
+
/**
Select styles
**/
@@ -148,27 +210,34 @@ Select styles
background-color: var(--card-background-color) !important;
border-color: var(--tag-border-color) !important;
}
+
.hackertab__indicator-separator {
background-color: var(--tag-secondary-color) !important;
}
+
.hackertab__indicator {
color: var(--tag-secondary-color) !important;
}
+
.hackertab__multi-value {
background-color: var(--tag-background-color) !important;
border-color: var(--tag-background-color) !important;
border-radius: 20px !important;
}
+
.hackertab__multi-value__label {
color: var(--tag-text-color) !important;
}
+
.hackertab__menu {
background-color: var(--card-background-color) !important;
}
+
.hackertab__option {
color: var(--tag-input-background) !important;
background-color: var(--card-background-color) !important;
}
+
.hackertab__single-value {
color: var(--primary-text-color) !important;
}
@@ -177,11 +246,26 @@ Select styles
background: var(--tag-background-color) !important;
color: var(--tag-text-color) !important;
}
+
.hackertab__multi-value__remove {
border-radius: 20px !important;
color: var(--tag-secondary-color) !important;
}
+.settingsGroup {
+ padding: 16px;
+ background-color: var(--card-background-color);
+ border: 1px solid var(--card-border-color);
+ border-radius: 8px;
+}
+
+.settingsGroupTitle {
+ font-weight: 600;
+ font-size: 16px;
+ color: var(--primary-text-color);
+ margin-bottom: 16px;
+}
+
@media (max-width: 768px) {
.Modal {
left: 0;
@@ -195,11 +279,13 @@ Select styles
box-shadow: none;
width: auto;
}
+
.settingContent {
margin-top: 6px;
}
+
.settingRow {
flex-direction: column;
align-items: flex-start;
}
-}
+}
\ No newline at end of file
diff --git a/src/lib/analytics.ts b/src/lib/analytics.ts
index c03674e1..443c364c 100644
--- a/src/lib/analytics.ts
+++ b/src/lib/analytics.ts
@@ -51,6 +51,7 @@ export enum Attributes {
DIRECTION = 'Direction',
SEARCH_ENGINE = 'Search Engine',
THEME = 'Theme',
+ THEME_MODE = 'Theme Mode',
LANGUAGE = 'Language',
LANGUAGES = 'Languages',
DATE_RANGE = 'Date Range',
@@ -155,6 +156,14 @@ export const trackThemeSelect = (theme: 'dark' | 'light') => {
})
}
+export const trackThemeModeSelect = (mode: 'auto' | 'manual') => {
+ trackEvent({
+ object: Objects.THEME,
+ verb: Verbs.SELECT,
+ attributes: { [Attributes.THEME_MODE]: mode },
+ })
+}
+
export const trackLanguageAdd = (languageName: string) => {
trackEvent({
object: Objects.LANGUAGE,
diff --git a/src/stores/preferences.ts b/src/stores/preferences.ts
index 43c527b5..7620ef27 100644
--- a/src/stores/preferences.ts
+++ b/src/stores/preferences.ts
@@ -12,11 +12,13 @@ import {
SelectedCard,
SupportedCardType,
Theme,
+ ThemePreferences
} from '../types'
export type UserPreferencesState = {
userSelectedTags: Tag[]
theme: Theme
+ themePreferences: ThemePreferences
openLinksNewTab: boolean
onboardingCompleted: boolean
onboardingResult: Omit | null
@@ -48,6 +50,7 @@ type UserPreferencesStoreActions = {
isDNDModeActive: () => boolean
addSearchEngine: (searchEngine: SearchEngineType) => void
removeSearchEngine: (searchEngineUrl: string) => void
+ setThemePreferences: (prefs: Partial) => void
}
const defaultStorage: StateStorage = {
@@ -118,6 +121,11 @@ export const useUserPreferences = create(
cardsSettings: {},
maxVisibleCards: 4,
theme: 'dark',
+ themePreferences: {
+ mode: 'manual',
+ autoStartHour: 19, // 7 PM
+ autoEndHour: 6, // 6 AM
+ },
onboardingCompleted: false,
onboardingResult: null,
searchEngine: 'chatgpt',
@@ -176,7 +184,11 @@ export const useUserPreferences = create(
DNDDuration: 'never',
setSearchEngine: (searchEngine: string) => set({ searchEngine: searchEngine }),
setListingMode: (listingMode: ListingMode) => set({ listingMode: listingMode }),
- setTheme: (theme: Theme) => set({ theme: theme }),
+ setTheme: (theme: Theme) => set({ theme }),
+ setThemePreferences: (prefs: Partial) =>
+ set((state) => ({
+ themePreferences: { ...state.themePreferences, ...prefs },
+ })),
setOpenLinksNewTab: (openLinksNewTab: boolean) => set({ openLinksNewTab: openLinksNewTab }),
setCards: (selectedCards: SelectedCard[]) => set({ cards: selectedCards }),
setTags: (selectedTags: Tag[]) => set({ userSelectedTags: selectedTags }),
diff --git a/src/types/index.ts b/src/types/index.ts
index 7ac14c23..501fb4fe 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -118,8 +118,15 @@ export type Option = {
export type DNDDuration =
| {
- value: number
- countdown: number
- }
+ value: number
+ countdown: number
+ }
| 'always'
| 'never'
+
+export type ThemeMode = 'auto' | 'manual'
+export type ThemePreferences = {
+ mode: ThemeMode
+ autoStartHour: number // 24-hour format
+ autoEndHour: number // 24-hour format
+}