refactor: pick out magic numbers to constants
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
// Application Constants
|
||||
// This file contains magic numbers and strings used in JavaScript/TypeScript logic
|
||||
|
||||
// ===== PANEL SETTINGS =====
|
||||
export const PANEL_SETTINGS = {
|
||||
// Storage
|
||||
STORAGE_KEY: "twitch-panels",
|
||||
MAX_PANELS_COUNT: 50,
|
||||
|
||||
// Dimensions
|
||||
PANEL_WIDTH: 320,
|
||||
PANEL_HEIGHT_DEFAULT: 100,
|
||||
PANEL_HEIGHT_MAX: 1000,
|
||||
|
||||
// Default values
|
||||
DEFAULT_BACKGROUND_IMAGE: "/backgrounds/b1.jpg",
|
||||
} as const;
|
||||
|
||||
// ===== TYPOGRAPHY =====
|
||||
export const TYPOGRAPHY = {
|
||||
// Font families
|
||||
FONT_FAMILY_DEFAULT: "Arial",
|
||||
FONT_FAMILIES: [
|
||||
"Arial",
|
||||
"Verdana",
|
||||
"Georgia",
|
||||
"Times New Roman",
|
||||
"Courier New",
|
||||
"Impact",
|
||||
"Comic Sans MS",
|
||||
"Trebuchet MS",
|
||||
],
|
||||
|
||||
// Font sizes for range inputs
|
||||
FONT_SIZE_MIN: 10,
|
||||
FONT_SIZE_MAX: 72,
|
||||
FONT_SIZE_DEFAULT: 18,
|
||||
|
||||
// Text alignment
|
||||
TEXT_ALIGN_LEFT: "left",
|
||||
TEXT_ALIGN_CENTER: "center",
|
||||
TEXT_ALIGN_RIGHT: "right",
|
||||
|
||||
// Text limits
|
||||
MAX_TEXT_LENGTH: 100,
|
||||
|
||||
// Padding for range inputs
|
||||
PADDING_X_DEFAULT: 10,
|
||||
PADDING_X_LARGE: 20,
|
||||
PADDING_X_MAX: 50,
|
||||
|
||||
// Vertical offset for range inputs
|
||||
VERTICAL_OFFSET_MAX: 50,
|
||||
VERTICAL_OFFSET_MIN: -50,
|
||||
|
||||
// Colors
|
||||
TEXT_COLOR_DEFAULT: "#ffffff",
|
||||
TEXT_COLOR_ERROR: "#c62828",
|
||||
} as const;
|
||||
|
||||
// ===== IMAGE SETTINGS =====
|
||||
export const IMAGE_SETTINGS = {
|
||||
// File sizes
|
||||
MAX_FILE_SIZE: 10 * 1024 * 1024, // 10MB
|
||||
|
||||
// Supported formats
|
||||
SUPPORTED_FORMATS: ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif"] as const,
|
||||
} as const;
|
||||
|
||||
// ===== UI SETTINGS =====
|
||||
export const UI_SETTINGS = {
|
||||
// Steps
|
||||
STEPS: {
|
||||
UPLOAD: "upload",
|
||||
CROP: "crop",
|
||||
TEXT: "text",
|
||||
} as const,
|
||||
} as const;
|
||||
|
||||
// ===== ERROR HANDLING =====
|
||||
export const ERROR_HANDLING = {
|
||||
// Retry settings
|
||||
MAX_RETRIES: 3,
|
||||
RETRY_DELAY_MS: 1000,
|
||||
} as const;
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AppError, type ErrorType } from "../types/errors";
|
||||
import { ERROR_HANDLING } from "../constants";
|
||||
import { AppError } from "../types/errors";
|
||||
|
||||
export function handleError(error: unknown, defaultMessage: string = "Произошла ошибка"): string {
|
||||
if (error instanceof AppError) {
|
||||
@@ -38,8 +39,8 @@ export function logError(error: unknown, context?: string): void {
|
||||
|
||||
export function retryOperation<T>(
|
||||
operation: () => Promise<T>,
|
||||
maxRetries: number = 3,
|
||||
delayMs: number = 1000,
|
||||
maxRetries: number = ERROR_HANDLING.MAX_RETRIES,
|
||||
delayMs: number = ERROR_HANDLING.RETRY_DELAY_MS,
|
||||
): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempt = 0;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { IMAGE_SETTINGS } from "../constants";
|
||||
import { ImageError } from "../types/errors";
|
||||
|
||||
export const MAX_FILE_SIZE = 10 * 1024 * 1024;
|
||||
export const SUPPORTED_FORMATS = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif"];
|
||||
export const MAX_FILE_SIZE = IMAGE_SETTINGS.MAX_FILE_SIZE;
|
||||
export const SUPPORTED_FORMATS = IMAGE_SETTINGS.SUPPORTED_FORMATS;
|
||||
|
||||
export type ValidationResult =
|
||||
| {
|
||||
@@ -23,7 +24,7 @@ export function validateFileSize(file: File): ValidationResult {
|
||||
}
|
||||
|
||||
export function validateFileType(file: File): ValidationResult {
|
||||
if (!SUPPORTED_FORMATS.includes(file.type)) {
|
||||
if (!SUPPORTED_FORMATS.includes(file.type as any)) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: `Неподдерживаемый формат. Допустимые форматы: ${SUPPORTED_FORMATS.join(", ")}`,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { PANEL_SETTINGS } from "../constants";
|
||||
import type { Panel } from "../types/panel";
|
||||
import { handleError, logError } from "./errorHandler";
|
||||
|
||||
const STORAGE_KEY = "twitch-panels";
|
||||
const MAX_PANELS = 50;
|
||||
const STORAGE_KEY = PANEL_SETTINGS.STORAGE_KEY;
|
||||
const MAX_PANELS = PANEL_SETTINGS.MAX_PANELS_COUNT;
|
||||
|
||||
export interface StorageResult {
|
||||
success: boolean;
|
||||
@@ -109,7 +110,7 @@ export class PanelStorage {
|
||||
Array.isArray(panel.texts) &&
|
||||
typeof panel.height === "number" &&
|
||||
panel.height > 0 &&
|
||||
panel.height <= 1000 &&
|
||||
panel.height <= PANEL_SETTINGS.PANEL_HEIGHT_MAX &&
|
||||
panel.createdAt instanceof Date &&
|
||||
panel.updatedAt instanceof Date
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user