chore(messages): update max file size to 5MB in multiple language files

This commit is contained in:
Fatih Kadir Akın
2025-12-14 00:29:35 +03:00
parent 8063451b7f
commit c32e035322
15 changed files with 190 additions and 29 deletions

View File

@@ -172,8 +172,8 @@
"mediaImage": "صورة الوسائط",
"clickToUpload": "انقر لرفع صورة",
"uploading": "جارٍ الرفع...",
"maxFileSize": "الحد الأقصى لحجم الملف: 1 ميجابايت (JPEG، PNG، GIF، WebP)",
"fileTooLarge": "الملف كبير جداً. الحد الأقصى للحجم هو 1 ميجابايت.",
"maxFileSize": "الحد الأقصى لحجم الملف: 5 ميجابايت (JPEG، PNG، GIF، WebP)",
"fileTooLarge": "الملف كبير جداً. الحد الأقصى للحجم هو 5 ميجابايت.",
"invalidFileType": "نوع ملف غير صالح. يُسمح فقط بـ JPEG و PNG و GIF و WebP.",
"privateDescription": "الأوامر الخاصة مرئية لك فقط",
"update": "تحديث",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Medienbild",
"clickToUpload": "Klicken Sie, um ein Bild hochzuladen",
"uploading": "Wird hochgeladen...",
"maxFileSize": "Max. Dateigröße: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Datei zu groß. Maximale Größe ist 1MB.",
"maxFileSize": "Max. Dateigröße: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Datei zu groß. Maximale Größe ist 5MB.",
"invalidFileType": "Ungültiger Dateityp. Nur JPEG, PNG, GIF und WebP sind erlaubt.",
"privateDescription": "Private Prompts sind nur für Sie sichtbar",
"requiresMediaUpload": "Medien-Upload erforderlich",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Media Image",
"clickToUpload": "Click to upload an image",
"uploading": "Uploading...",
"maxFileSize": "Max file size: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "File too large. Maximum size is 1MB.",
"maxFileSize": "Max file size: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "File too large. Maximum size is 5MB.",
"invalidFileType": "Invalid file type. Only JPEG, PNG, GIF, and WebP are allowed.",
"privateDescription": "Private prompts are only visible to you",
"requiresMediaUpload": "Requires Media Upload",

View File

@@ -172,8 +172,8 @@
"mediaImage": "Imagen de Medios",
"clickToUpload": "Haz clic para subir una imagen",
"uploading": "Subiendo...",
"maxFileSize": "Tamaño máximo: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Archivo demasiado grande. El tamaño máximo es 1MB.",
"maxFileSize": "Tamaño máximo: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Archivo demasiado grande. El tamaño máximo es 5MB.",
"invalidFileType": "Tipo de archivo inválido. Solo se permiten JPEG, PNG, GIF y WebP.",
"privateDescription": "Los prompts privados solo son visibles para ti",
"update": "Actualizar",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Image Média",
"clickToUpload": "Cliquez pour télécharger une image",
"uploading": "Téléchargement...",
"maxFileSize": "Taille max: 1Mo (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Fichier trop volumineux. La taille maximale est de 1Mo.",
"maxFileSize": "Taille max: 5Mo (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Fichier trop volumineux. La taille maximale est de 5Mo.",
"invalidFileType": "Type de fichier invalide. Seuls JPEG, PNG, GIF et WebP sont autorisés.",
"privateDescription": "Les prompts privés ne sont visibles que par vous",
"requiresMediaUpload": "Nécessite un Upload de Média",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Immagine Media",
"clickToUpload": "Clicca per caricare un'immagine",
"uploading": "Caricamento...",
"maxFileSize": "Dimensione max: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "File troppo grande. La dimensione massima è 1MB.",
"maxFileSize": "Dimensione max: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "File troppo grande. La dimensione massima è 5MB.",
"invalidFileType": "Tipo di file non valido. Sono consentiti solo JPEG, PNG, GIF e WebP.",
"privateDescription": "I prompt privati sono visibili solo a te",
"requiresMediaUpload": "Richiede Caricamento Media",

View File

@@ -172,8 +172,8 @@
"mediaImage": "メディア画像",
"clickToUpload": "クリックして画像をアップロード",
"uploading": "アップロード中...",
"maxFileSize": "最大ファイルサイズ: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "ファイルが大きすぎます。最大サイズは1MBです。",
"maxFileSize": "最大ファイルサイズ: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "ファイルが大きすぎます。最大サイズは5MBです。",
"invalidFileType": "無効なファイル形式です。JPEG、PNG、GIF、WebPのみ許可されています。",
"privateDescription": "非公開プロンプトはあなただけに表示されます",
"update": "更新",

View File

@@ -165,8 +165,8 @@
"mediaImage": "미디어 이미지",
"clickToUpload": "클릭하여 이미지 업로드",
"uploading": "업로드 중...",
"maxFileSize": "최대 파일 크기: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "파일이 너무 큽니다. 최대 크기는 1MB입니다.",
"maxFileSize": "최대 파일 크기: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "파일이 너무 큽니다. 최대 크기는 5MB입니다.",
"invalidFileType": "잘못된 파일 형식입니다. JPEG, PNG, GIF, WebP만 허용됩니다.",
"privateDescription": "비공개 프롬프트는 본인만 볼 수 있습니다",
"requiresMediaUpload": "미디어 업로드 필요",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Imagem de Mídia",
"clickToUpload": "Clique para enviar uma imagem",
"uploading": "Enviando...",
"maxFileSize": "Tamanho máximo: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Arquivo muito grande. O tamanho máximo é 1MB.",
"maxFileSize": "Tamanho máximo: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Arquivo muito grande. O tamanho máximo é 5MB.",
"invalidFileType": "Tipo de arquivo inválido. Apenas JPEG, PNG, GIF e WebP são permitidos.",
"privateDescription": "Prompts privados são visíveis apenas para você",
"requiresMediaUpload": "Requer Upload de Mídia",

View File

@@ -165,8 +165,8 @@
"mediaImage": "Medya Görseli",
"clickToUpload": "Görsel yüklemek için tıklayın",
"uploading": "Yükleniyor...",
"maxFileSize": "Maksimum dosya boyutu: 1MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Dosya çok büyük. Maksimum boyut 1MB'dir.",
"maxFileSize": "Maksimum dosya boyutu: 5MB (JPEG, PNG, GIF, WebP)",
"fileTooLarge": "Dosya çok büyük. Maksimum boyut 5MB'dir.",
"invalidFileType": "Geçersiz dosya türü. Yalnızca JPEG, PNG, GIF ve WebP'ye izin verilir.",
"privateDescription": "Özel promptlar yalnızca size görünür",
"requiresMediaUpload": "Medya Yüklemesi Gerekli",

View File

@@ -165,8 +165,8 @@
"mediaImage": "媒体图片",
"clickToUpload": "点击上传图片",
"uploading": "上传中...",
"maxFileSize": "最大文件大小:1MBJPEG、PNG、GIF、WebP",
"fileTooLarge": "文件太大。最大大小为1MB。",
"maxFileSize": "最大文件大小:5MBJPEG、PNG、GIF、WebP",
"fileTooLarge": "文件太大。最大大小为5MB。",
"invalidFileType": "无效的文件类型。仅允许JPEG、PNG、GIF和WebP。",
"privateDescription": "私有提示词仅对您可见",
"requiresMediaUpload": "需要媒体上传",

156
scripts/rebuild-history.sh Executable file
View File

@@ -0,0 +1,156 @@
#!/bin/bash
# ONE-TIME SCRIPT: Rebuild prompts.csv git history with contributor ownership
# This script will:
# 1. Remove prompts.csv from git history
# 2. Recreate it with individual commits for each prompt, attributed to their contributors
#
# WARNING: This rewrites git history! Only run this once, then delete this script.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CSV_FILE="$PROJECT_DIR/prompts.csv"
BACKUP_FILE="$PROJECT_DIR/prompts.csv.backup"
echo "=== Rebuild prompts.csv History ==="
echo ""
echo "WARNING: This will rewrite git history for prompts.csv!"
echo "Make sure you have a backup and coordinate with your team."
echo ""
read -p "Continue? (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "Aborted."
exit 1
fi
# Backup current prompts.csv
cp "$CSV_FILE" "$BACKUP_FILE"
echo "Backed up prompts.csv to prompts.csv.backup"
# Store current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
cd "$PROJECT_DIR"
# Run the Python script to rebuild history
export PROJECT_DIR
python3 << 'PYTHON_SCRIPT'
import csv
import subprocess
import os
project_dir = os.environ.get('PROJECT_DIR', '.')
csv_file = os.path.join(project_dir, 'prompts.csv')
backup_file = os.path.join(project_dir, 'prompts.csv.backup')
# Read all prompts from backup
prompts = []
fieldnames = None
with open(backup_file, 'r') as f:
reader = csv.DictReader(f)
fieldnames = reader.fieldnames
for row in reader:
prompts.append(row)
print(f"Found {len(prompts)} prompts to process")
# Helper function to parse contributors
def parse_contributors(contributor_field):
"""Parse contributor field, returns (primary_author, co_authors_list)"""
if not contributor_field:
return 'anonymous', []
contributors = [c.strip() for c in contributor_field.split(',') if c.strip()]
if not contributors:
return 'anonymous', []
primary = contributors[0]
co_authors = contributors[1:] if len(contributors) > 1 else []
return primary, co_authors
def build_commit_message(act, co_authors):
"""Build commit message with optional co-author trailers"""
msg = f'Add prompt: {act}'
if co_authors:
msg += '\n\n'
for co_author in co_authors:
co_email = f"{co_author}@users.noreply.github.com"
msg += f'Co-authored-by: {co_author} <{co_email}>\n'
return msg
# Remove prompts.csv from git (but keep the file)
print("\nRemoving prompts.csv from git tracking...")
subprocess.run(['git', 'rm', '--cached', csv_file], check=False)
# Create empty CSV with header
print("Creating empty prompts.csv with header...")
with open(csv_file, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
# Commit header
subprocess.run(['git', 'add', csv_file], check=True)
subprocess.run([
'git', 'commit',
'-m', 'Initialize prompts.csv',
'--author=f <f@users.noreply.github.com>'
], check=True)
print(f"\nCreating {len(prompts)} commits with contributor ownership...")
# Add each prompt with proper attribution
for i, row in enumerate(prompts, 1):
contributor_field = row.get('contributor', '').strip()
act = row.get('act', 'Unknown')
primary_author, co_authors = parse_contributors(contributor_field)
email = f"{primary_author}@users.noreply.github.com"
# Append this row to the CSV (only include known fieldnames)
with open(csv_file, 'a', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction='ignore')
writer.writerow(row)
# Stage and commit
subprocess.run(['git', 'add', csv_file], check=True)
env = os.environ.copy()
env['GIT_AUTHOR_NAME'] = primary_author
env['GIT_AUTHOR_EMAIL'] = email
env['GIT_COMMITTER_NAME'] = primary_author
env['GIT_COMMITTER_EMAIL'] = email
commit_msg = build_commit_message(act, co_authors)
subprocess.run([
'git', 'commit',
'-m', commit_msg,
f'--author={primary_author} <{email}>'
], env=env, check=True)
co_authors_str = f" (+ {', '.join(co_authors)})" if co_authors else ""
print(f"[{i}/{len(prompts)}] {primary_author}{co_authors_str}: {act}")
print(f"\nDone! Created {len(prompts)} commits with proper contributor attribution.")
print("\nTo push (force required since history changed):")
print(" git push origin main --force")
PYTHON_SCRIPT
# Clean up backup
rm -f "$BACKUP_FILE"
echo ""
echo "=== History Rebuilt ==="
echo ""
echo "Review with: git log --oneline prompts.csv | head -20"
echo ""
echo "To push (FORCE REQUIRED):"
echo " git push origin main --force"
echo ""
echo "DELETE THIS SCRIPT after use: rm scripts/rebuild-history.sh"

View File

@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getStoragePlugin } from "@/lib/plugins/registry";
const MAX_FILE_SIZE = 1 * 1024 * 1024; // 1MB
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
async function compressToJpg(buffer: Buffer): Promise<Buffer> {
@@ -71,7 +71,7 @@ export async function POST(request: NextRequest) {
// Validate file size
if (file.size > MAX_FILE_SIZE) {
return NextResponse.json(
{ error: "File too large. Maximum size is 1MB." },
{ error: "File too large. Maximum size is 5MB." },
{ status: 400 }
);
}

View File

@@ -32,7 +32,7 @@ export function MediaPreview({ mediaUrl, title, type }: MediaPreviewProps) {
}
return (
<div className="rounded-lg overflow-hidden border bg-muted/30">
<div className="rounded-lg overflow-hidden border bg-muted/30 relative">
{type === "VIDEO" ? (
<video
src={mediaUrl}
@@ -45,13 +45,18 @@ export function MediaPreview({ mediaUrl, title, type }: MediaPreviewProps) {
href={mediaUrl}
target="_blank"
rel="noopener noreferrer"
className="block"
className="block relative"
>
{/* Blurred background for vertical images */}
<div
className="absolute inset-0 bg-cover bg-center blur-2xl opacity-50 scale-110"
style={{ backgroundImage: `url(${mediaUrl})` }}
/>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={mediaUrl}
alt={title}
className="w-full max-h-[500px] object-contain block"
className="relative w-full max-h-[500px] object-contain block"
onError={() => setHasError(true)}
/>
</a>

View File

@@ -57,8 +57,8 @@ function MediaField({ form, t }: MediaFieldProps) {
const file = e.target.files?.[0];
if (!file) return;
// Validate file size (1MB)
if (file.size > 1 * 1024 * 1024) {
// Validate file size (5MB)
if (file.size > 5 * 1024 * 1024) {
setUploadError(t("fileTooLarge"));
return;
}