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';
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) {
const cloned = req.clone({
+9
View File
@@ -165,14 +165,21 @@
margin: 0 0 $spacing-md;
line-height: 1.5;
// WebKit line-clamp (Chrome, Safari)
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
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;
&.expanded {
-webkit-line-clamp: unset;
line-clamp: unset;
overflow: visible;
}
}
@@ -241,6 +248,7 @@
.show-description {
-webkit-line-clamp: 2;
line-clamp: 2;
font-size: 0.88rem;
}
}
@@ -263,5 +271,6 @@
.show-description {
-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';
// ── 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({
providedIn: 'root',
})
@@ -30,7 +56,7 @@ export class AuthService {
username,
password,
}).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`, {
id_token: idToken,
}).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. */
logout(): void {
localStorage.removeItem(TOKEN_KEY);
safeLocalStorageRemove(TOKEN_KEY);
this.authStateSubject.next(null);
}
@@ -83,7 +109,7 @@ export class AuthService {
// ── Private ──────────────────────────────────────────────
private _getToken(): string | null {
return localStorage.getItem(TOKEN_KEY);
return safeLocalStorageGet(TOKEN_KEY);
}
private async _initAuth(): Promise<void> {
+6
View File
@@ -19,6 +19,12 @@
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
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 {