Pro firefox enhancements

This commit is contained in:
2026-06-26 06:23:38 +00:00
parent 5188777556
commit bce9f8663d
4 changed files with 51 additions and 5 deletions
+6 -1
View File
@@ -1,7 +1,12 @@
import { HttpInterceptorFn, HttpRequest, HttpHandlerFn } from '@angular/common/http'; import { HttpInterceptorFn, HttpRequest, HttpHandlerFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => { export const authInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {
const token = localStorage.getItem('kmtn_access_token'); let token: string | null = null;
try {
token = localStorage.getItem('kmtn_access_token');
} catch {
// Storage blocked (e.g. Mullvad Browser strict mode)
}
if (token) { if (token) {
const cloned = req.clone({ const cloned = req.clone({
+9
View File
@@ -165,14 +165,21 @@
margin: 0 0 $spacing-md; margin: 0 0 $spacing-md;
line-height: 1.5; line-height: 1.5;
// WebKit line-clamp (Chrome, Safari)
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
// Standard line-clamp (Firefox 122+) — overrides display for supporting browsers
display: block;
line-clamp: 3;
transition: max-height $transition-slow ease, opacity $transition-normal; transition: max-height $transition-slow ease, opacity $transition-normal;
&.expanded { &.expanded {
-webkit-line-clamp: unset; -webkit-line-clamp: unset;
line-clamp: unset;
overflow: visible; overflow: visible;
} }
} }
@@ -241,6 +248,7 @@
.show-description { .show-description {
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2;
font-size: 0.88rem; font-size: 0.88rem;
} }
} }
@@ -263,5 +271,6 @@
.show-description { .show-description {
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2;
} }
} }
+30 -4
View File
@@ -7,6 +7,32 @@ import { AppUser, AuthTokenResponse } from '../interfaces/auth';
const TOKEN_KEY = 'kmtn_access_token'; const TOKEN_KEY = 'kmtn_access_token';
// ── Safe localStorage helpers (privacy browsers may throw SecurityError) ──
function safeLocalStorageGet(key: string): string | null {
try {
return localStorage.getItem(key);
} catch {
return null;
}
}
function safeLocalStorageSet(key: string, value: string): void {
try {
localStorage.setItem(key, value);
} catch {
// Storage blocked — silently ignore
}
}
function safeLocalStorageRemove(key: string): void {
try {
localStorage.removeItem(key);
} catch {
// Storage blocked — silently ignore
}
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
@@ -30,7 +56,7 @@ export class AuthService {
username, username,
password, password,
}).pipe( }).pipe(
tap((resp) => localStorage.setItem(TOKEN_KEY, resp.access_token)), tap((resp) => safeLocalStorageSet(TOKEN_KEY, resp.access_token)),
); );
} }
@@ -39,13 +65,13 @@ export class AuthService {
return this.http.post<AuthTokenResponse>(`${this.baseUrl}/google`, { return this.http.post<AuthTokenResponse>(`${this.baseUrl}/google`, {
id_token: idToken, id_token: idToken,
}).pipe( }).pipe(
tap((resp) => localStorage.setItem(TOKEN_KEY, resp.access_token)), tap((resp) => safeLocalStorageSet(TOKEN_KEY, resp.access_token)),
); );
} }
/** Clear stored token and reset auth state. */ /** Clear stored token and reset auth state. */
logout(): void { logout(): void {
localStorage.removeItem(TOKEN_KEY); safeLocalStorageRemove(TOKEN_KEY);
this.authStateSubject.next(null); this.authStateSubject.next(null);
} }
@@ -83,7 +109,7 @@ export class AuthService {
// ── Private ────────────────────────────────────────────── // ── Private ──────────────────────────────────────────────
private _getToken(): string | null { private _getToken(): string | null {
return localStorage.getItem(TOKEN_KEY); return safeLocalStorageGet(TOKEN_KEY);
} }
private async _initAuth(): Promise<void> { private async _initAuth(): Promise<void> {
+6
View File
@@ -19,6 +19,12 @@
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
// Firefox fallback: solid color when gradient text is unsupported
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
background: none;
color: $from;
}
} }
@mixin card-style { @mixin card-style {