diff --git a/messages/ar.json b/messages/ar.json index da84ddc3..62c8e7bc 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -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": "تحديث", diff --git a/messages/de.json b/messages/de.json index ed9d2107..2f275e0f 100644 --- a/messages/de.json +++ b/messages/de.json @@ -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", diff --git a/messages/en.json b/messages/en.json index 0f0b2767..b633e59a 100644 --- a/messages/en.json +++ b/messages/en.json @@ -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", diff --git a/messages/es.json b/messages/es.json index bc791c59..b32a8382 100644 --- a/messages/es.json +++ b/messages/es.json @@ -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", diff --git a/messages/fr.json b/messages/fr.json index 9808e782..2ee40ce0 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -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", diff --git a/messages/it.json b/messages/it.json index f51c3cd8..f7a4d05d 100644 --- a/messages/it.json +++ b/messages/it.json @@ -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", diff --git a/messages/ja.json b/messages/ja.json index 91f8dcf6..7cb97288 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -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": "更新", diff --git a/messages/ko.json b/messages/ko.json index 4a2c864d..0ad2bdf2 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -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": "미디어 업로드 필요", diff --git a/messages/pt.json b/messages/pt.json index a6a1ed57..7dea1543 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -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", diff --git a/messages/tr.json b/messages/tr.json index 9f0f3316..6b1c84ac 100644 --- a/messages/tr.json +++ b/messages/tr.json @@ -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", diff --git a/messages/zh.json b/messages/zh.json index 0cf8cab5..526bd566 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -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": "需要媒体上传", diff --git a/scripts/rebuild-history.sh b/scripts/rebuild-history.sh new file mode 100755 index 00000000..7677f700 --- /dev/null +++ b/scripts/rebuild-history.sh @@ -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 ' +], 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" diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 91ccf300..e6258eda 100644 --- a/src/app/api/upload/route.ts +++ b/src/app/api/upload/route.ts @@ -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 { @@ -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 } ); } diff --git a/src/components/prompts/media-preview.tsx b/src/components/prompts/media-preview.tsx index 8fa11a8e..3f805d31 100644 --- a/src/components/prompts/media-preview.tsx +++ b/src/components/prompts/media-preview.tsx @@ -32,7 +32,7 @@ export function MediaPreview({ mediaUrl, title, type }: MediaPreviewProps) { } return ( -
+
{type === "VIDEO" ? (