removed old drawer stuff

This commit is contained in:
nvrl committed 2026-06-16 23:31:35 +02:00
1 parent e714e1ea51
commit 5ff5da2aac
8 files changed
+2 -102

No files matched your search

-1
View File
@@ -109,7 +109,6 @@ pub struct UserOut {
pub email: String, pub email: String,
pub theme: String, pub theme: String,
pub language: String, pub language: String,
pub drawer_anchor: String,
pub avatar: Option<String>, pub avatar: Option<String>,
pub following_count: i64, pub following_count: i64,
pub followers_count: i64, pub followers_count: i64,
-1
View File
@@ -25,7 +25,6 @@ pub struct Model {
pub avatar: Option<String>, pub avatar: Option<String>,
pub language: String, pub language: String,
pub selected_banner_id: Option<i32>, pub selected_banner_id: Option<i32>,
pub drawer_anchor: String,
/// Dedicated account-deletion confirmation code + its expiry. Kept separate /// Dedicated account-deletion confirmation code + its expiry. Kept separate
/// from `email_confirmation_code` so other code-driven flows (email confirm, /// from `email_confirmation_code` so other code-driven flows (email confirm,
/// password reset) can never clobber an in-flight deletion code, and /// password reset) can never clobber an in-flight deletion code, and
-9
View File
@@ -63,7 +63,6 @@ const THEMES: &[&str] = &[
"t0p_clancy", "t0p_clancy",
]; ];
const LANGUAGES: &[&str] = &["en", "de"]; const LANGUAGES: &[&str] = &["en", "de"];
const DRAWER_ANCHORS: &[&str] = &["left", "right"];
pub fn router() -> Router<AppState> { pub fn router() -> Router<AppState> {
Router::new() Router::new()
@@ -434,12 +433,6 @@ async fn update_preferences(
updated = true; updated = true;
} }
} }
if let Some(da) = data.get("drawer_anchor").and_then(|v| v.as_str()) {
if DRAWER_ANCHORS.contains(&da) {
active.drawer_anchor = Set(da.to_string());
updated = true;
}
}
// selected_banner: present + non-null. "" clears; otherwise must be enabled. // selected_banner: present + non-null. "" clears; otherwise must be enabled.
match data.get("selected_banner") { match data.get("selected_banner") {
@@ -489,7 +482,6 @@ async fn update_preferences(
"status": "preferences updated", "status": "preferences updated",
"theme": saved.theme, "theme": saved.theme,
"language": saved.language, "language": saved.language,
"drawer_anchor": saved.drawer_anchor,
"selected_banner": saved.selected_banner_id, "selected_banner": saved.selected_banner_id,
}))) })))
} }
@@ -763,7 +755,6 @@ async fn signup(
avatar: Set(None), avatar: Set(None),
language: Set("en".into()), language: Set("en".into()),
selected_banner_id: Set(None), selected_banner_id: Set(None),
drawer_anchor: Set("right".into()),
..Default::default() ..Default::default()
} }
.insert(&state.db) .insert(&state.db)
-1
View File
@@ -758,7 +758,6 @@ pub async fn build_users(
email: u.email, email: u.email,
theme: u.theme, theme: u.theme,
language: u.language, language: u.language,
drawer_anchor: u.drawer_anchor,
}) })
.collect()) .collect())
} }
-1
View File
@@ -7,7 +7,6 @@ export interface AuthUser {
is_superuser: boolean; is_superuser: boolean;
theme?: string; theme?: string;
language?: string; language?: string;
drawer_anchor?: 'left' | 'right';
} }
export interface FollowingEntry { export interface FollowingEntry {
-55
View File
@@ -1,55 +0,0 @@
import { useCallback, useEffect, useState } from 'react';
import api from '../lib/api';
import { useAuth } from './useAuth';
export type DrawerAnchor = 'left' | 'right';
const STORAGE_KEY = 'drawer-anchor';
const readLocal = (): DrawerAnchor => {
const raw = localStorage.getItem(STORAGE_KEY);
return raw === 'left' ? 'left' : 'right';
};
export interface UseDrawerAnchorResult {
anchor: DrawerAnchor;
setAnchor: (anchor: DrawerAnchor) => Promise<void>;
}
export const useDrawerAnchor = (): UseDrawerAnchorResult => {
const { user, refetchUser } = useAuth();
const [anchor, setAnchorState] = useState<DrawerAnchor>(
(user?.drawer_anchor as DrawerAnchor) ?? readLocal(),
);
// Adopt the server-side preference when it loads/changes. Derived during
// render (tracking the previously-applied value) so it doesn't cost an extra
// effect pass; the localStorage mirror is written in the effect below.
const [appliedAnchor, setAppliedAnchor] = useState(user?.drawer_anchor);
if (user?.drawer_anchor && user.drawer_anchor !== appliedAnchor) {
setAppliedAnchor(user.drawer_anchor);
setAnchorState(user.drawer_anchor);
}
useEffect(() => {
if (user?.drawer_anchor) localStorage.setItem(STORAGE_KEY, user.drawer_anchor);
}, [user?.drawer_anchor]);
const setAnchor = useCallback(
async (next: DrawerAnchor) => {
setAnchorState(next);
localStorage.setItem(STORAGE_KEY, next);
if (user) {
try {
await api.patch('users/update_preferences/', { drawer_anchor: next });
await refetchUser();
} catch {
/* fall back to local-only persistence */
}
}
},
[user, refetchUser],
);
return { anchor, setAnchor };
};
+2 -5
View File
@@ -9,7 +9,6 @@ import {
IconButton, IconButton,
Skeleton, Skeleton,
useMediaQuery, useMediaQuery,
useTheme,
} from '@mui/material'; } from '@mui/material';
import { Link, useLocation } from 'react-router-dom'; import { Link, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@@ -94,8 +93,6 @@ const MainPage: React.FC = () => {
const [autoPlay, setAutoPlay] = useState(true); const [autoPlay, setAutoPlay] = useState(true);
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false);
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)'); const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
const muiTheme = useTheme();
const isDesktop = useMediaQuery(muiTheme.breakpoints.up('md'));
const touchStartX = useRef<number | null>(null); const touchStartX = useRef<number | null>(null);
const query = new URLSearchParams(location.search).get('q') || ''; const query = new URLSearchParams(location.search).get('q') || '';
@@ -533,8 +530,8 @@ const MainPage: React.FC = () => {
)} )}
</Box> </Box>
{/* Desktop-only category browser */} {/* Category browser */}
{isDesktop && <CategoryBrowseGrid categories={categories} />} <CategoryBrowseGrid categories={categories} />
{/* Algorithmic discovery: personalized (members) or popular picks (visitors) */} {/* Algorithmic discovery: personalized (members) or popular picks (visitors) */}
<MainPageRecommendations isLoggedIn={isLoggedIn} /> <MainPageRecommendations isLoggedIn={isLoggedIn} />
-29
View File
@@ -24,8 +24,6 @@ import {
ListSubheader, ListSubheader,
Divider, Divider,
Grid, Grid,
FormControlLabel,
Switch,
} from '@mui/material'; } from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { useNavigate, useSearchParams } from 'react-router-dom'; import { useNavigate, useSearchParams } from 'react-router-dom';
@@ -36,7 +34,6 @@ import { useTitle } from '../hooks/useTitle';
import type { CatppuccinTheme } from '../theme'; import type { CatppuccinTheme } from '../theme';
import { PageShell, GlassCard, FormCard } from '../components/ui'; import { PageShell, GlassCard, FormCard } from '../components/ui';
import { useConfirm } from '../hooks/useConfirm'; import { useConfirm } from '../hooks/useConfirm';
import { useDrawerAnchor } from '../hooks/useDrawerAnchor';
interface SettingsProps { interface SettingsProps {
themeName: CatppuccinTheme; themeName: CatppuccinTheme;
@@ -54,7 +51,6 @@ const Settings: React.FC<SettingsProps> = ({ themeName, onThemeChange }) => {
const { refetchUser } = useAuth(); const { refetchUser } = useAuth();
useTitle(t('nav.settings')); useTitle(t('nav.settings'));
const { confirm } = useConfirm(); const { confirm } = useConfirm();
const { anchor: drawerAnchor, setAnchor: setDrawerAnchor } = useDrawerAnchor();
const { data: me } = useMe(); const { data: me } = useMe();
const { data: banners = [] } = useBannersList(); const { data: banners = [] } = useBannersList();
const updateAvatarMutation = useUpdateAvatar(); const updateAvatarMutation = useUpdateAvatar();
@@ -324,31 +320,6 @@ const Settings: React.FC<SettingsProps> = ({ themeName, onThemeChange }) => {
<MenuItem value="de">Deutsch</MenuItem> <MenuItem value="de">Deutsch</MenuItem>
</Select> </Select>
</FormControl> </FormControl>
<Divider sx={{ my: 2 }} />
<FormControlLabel
control={
<Switch
checked={drawerAnchor === 'left'}
onChange={(e) => setDrawerAnchor(e.target.checked ? 'left' : 'right')}
/>
}
label={
<Box>
<Typography variant="body1">
{t('settings.leftHandMode', { defaultValue: 'Left-hand mode' })}
</Typography>
<Typography variant="caption" color="text.secondary">
{t('settings.leftHandModeHint', {
defaultValue:
'Mobile drawer slides in from the left (better for left-handed thumb reach).',
})}
</Typography>
</Box>
}
sx={{ alignItems: 'flex-start', mt: 1 }}
/>
</GlassCard> </GlassCard>
{/* Avatar: NOT a FormCard — file input lives outside any form */} {/* Avatar: NOT a FormCard — file input lives outside any form */}