proxybuy-flutter/LANGUAGE_SYSTEM_DOCUMENTATI...

11 KiB
Raw Blame History

🌐 سیستم تغییر زبان در اپلیکیشن LBA

📋 فهرست مطالب

  1. معرفی کلی
  2. ساختار فایل‌ها
  3. زبان‌های پشتیبانی شده
  4. کامپوننت‌های کلیدی
  5. نحوه پیاده‌سازی
  6. مدیریت State
  7. UI/UX طراحی
  8. نکات فنی
  9. استفاده در صفحات مختلف
  10. عیب‌یابی

🎯 معرفی کلی

سیستم تغییر زبان در اپ LBA امکان انتخاب بین سه زبان انگلیسی، عربی و فارسی را فراهم می‌کند. این سیستم در دو صفحه اصلی قابل دسترسی است:

  • صفحه Onboarding (بالای راست)
  • صفحه Profile (بخش تنظیمات)

📁 ساختار فایل‌ها

lib/
├── widgets/
│   └── language_selection_dialog.dart     # کامپوننت اصلی انتخاب زبان
├── screens/
│   ├── auth/
│   │   └── onboarding_page.dart          # صفحه معرفی با انتخاب زبان
│   └── mains/profile/
│       └── profile.dart                   # صفحه پروفایل
├── gen/
│   └── assets.gen.dart                   # فایل‌های asset تولید شده
└── res/
    └── colors.dart                       # رنگ‌های اپلیکیشن

🌍 زبان‌های پشتیبانی شده

زبان کد پرچم فایل آیکون
English en 🇺🇲 assets/icons/usa circle.svg
العربية ar 🇦🇪 assets/icons/arab circle.svg
فارسی fa 🇮🇷 assets/icons/iran circle.svg

🔧 کامپوننت‌های کلیدی

1. LanguageSelectionOverlay

کامپوننت اصلی که overlay انتخاب زبان را نمایش می‌دهد.

پراپ‌های ورودی:

final String currentLanguage;                    // زبان فعلی
final Function(String language, String flag) onLanguageSelected;  // کالبک انتخاب
final GlobalKey targetKey;                       // کلید موقعیت‌یابی

2. showLanguageSelectionOverlay

تابع کمکی برای نمایش overlay:

void showLanguageSelectionOverlay(
  BuildContext context,
  String currentLanguage,
  Function(String language, String flag) onLanguageSelected,
  GlobalKey targetKey,
)

🛠 نحوه پیاده‌سازی

مرحله 1: اضافه کردن State متغیرها

class _YourPageState extends State<YourPage> {
  String _currentLanguage = '🇺🇲  English';
  String _currentFlag = 'assets/icons/usa circle.svg';
  final GlobalKey _languageKey = GlobalKey();
  
  // ... سایر کدها
}

مرحله 2: ایجاد UI انتخاب زبان

GestureDetector(
  key: _languageKey,
  onTap: () {
    showLanguageSelectionOverlay(
      context,
      _currentLanguage,
      (language, flag) {
        setState(() {
          _currentLanguage = language;
          _currentFlag = flag;
        });
      },
      _languageKey,
    );
  },
  child: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      // نمایش پرچم
      AnimatedSwitcher(
        duration: const Duration(milliseconds: 300),
        child: ClipRRect(
          key: ValueKey(_currentFlag),
          borderRadius: BorderRadius.circular(4),
          child: SvgPicture.asset(
            _currentFlag,
            width: 24,
            height: 18,
          ),
        ),
      ),
      const SizedBox(width: 8),
      // نمایش نام زبان
      AnimatedSwitcher(
        duration: const Duration(milliseconds: 300),
        child: Text(
          _currentLanguage,
          key: ValueKey(_currentLanguage),
          style: TextStyle(
            fontSize: 15,
            fontWeight: FontWeight.w500,
            color: AppColors.textPrimary,
          ),
        ),
      ),
      const SizedBox(width: 8),
      // آیکون فلش
      SvgPicture.asset(
        Assets.icons.arrowRight.path,
        color: AppColors.textPrimary,
      ),
    ],
  ),
),

مرحله 3: اضافه کردن Import ها

import 'package:flutter_svg/flutter_svg.dart';
import '../../widgets/language_selection_dialog.dart';
import '../../gen/assets.gen.dart';
import '../../res/colors.dart';

🔄 مدیریت State

Local State Management

هر صفحه state زبان خود را به‌صورت جداگانه مدیریت می‌کند:

// متغیرهای state
String _currentLanguage = '🇺🇲  English';  // نام کامل زبان با پرچم
String _currentFlag = 'assets/icons/usa circle.svg';  // مسیر فایل پرچم

// تابع تغییر زبان
void _changeLanguage(String language, String flag) {
  setState(() {
    _currentLanguage = language;
    _currentFlag = flag;
  });
}

Persistence (در آینده)

برای ذخیره انتخاب زبان کاربر می‌توان از SharedPreferences استفاده کرد:

// ذخیره زبان
Future<void> _saveLanguage(String languageCode) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('selected_language', languageCode);
}

// بازیابی زبان
Future<String> _loadLanguage() async {
  final prefs = await SharedPreferences.getInstance();
  return prefs.getString('selected_language') ?? 'en';
}

🎨 UI/UX طراحی

Positioning Logic

سیستم positioning هوشمند برای مکان‌یابی overlay:

// تشخیص موقعیت target در صفحه
if (targetPosition.dx > screenWidth * 0.7) {
    // انتهای راست (مثل onboarding)
    rightPosition = 16;
} else {
    // وسط یا چپ (مثل profile)  
    rightPosition = 24;
}

Animation ها

  • Scale Animation: ورود overlay با افکت scale
  • Opacity Animation: fade in/out
  • Switcher Animation: تغییر پرچم و متن با AnimatedSwitcher
AnimationController _animationController = AnimationController(
  vsync: this,
  duration: const Duration(milliseconds: 300),
);

Animation<double> _scaleAnimation = Tween<double>(
  begin: 0.8, 
  end: 1.0
).animate(CurvedAnimation(
  parent: _animationController, 
  curve: Curves.easeOutBack
));

طراحی Overlay

Container(
  decoration: BoxDecoration(
    color: AppColors.surface,
    borderRadius: BorderRadius.only(
      bottomLeft: Radius.circular(16),
      bottomRight: Radius.circular(16),
      topLeft: Radius.circular(16),
    ),
    boxShadow: [
      BoxShadow(
        color: AppColors.shadowColor,
        blurRadius: 15,
        spreadRadius: 3,
        offset: const Offset(0, 5),
      ),
    ],
  ),
  // محتوای overlay
)

نکات فنی

1. Error Handling

برای مواردی که asset پرچم بارگذاری نشود:

errorBuilder: (context, error, stackTrace) {
  return Container(
    width: 24,
    height: 18,
    decoration: BoxDecoration(
      color: AppColors.greyBorder.withOpacity(0.2),
      borderRadius: BorderRadius.circular(4),
    ),
    child: Icon(
      Icons.flag,
      color: AppColors.textSecondary,
      size: 12,
    ),
  );
}

2. Responsive Design

سیستم با اندازه‌های مختلف صفحه سازگار است:

final overlayWidth = screenWidth * 0.45;  // 45% عرض صفحه

3. RTL Support

پشتیبانی از زبان‌های راست به چپ:

textDirection: (code == 'ar' || code == 'fa')
    ? TextDirection.rtl
    : TextDirection.ltr,

4. Performance

استفاده از ValueKey برای بهینه‌سازی rebuilds:

AnimatedSwitcher(
  child: Widget(
    key: ValueKey(_currentLanguage),  // جلوگیری از rebuild غیرضروری
    // ...
  ),
)

📱 استفاده در صفحات مختلف

صفحه Onboarding

// موقعیت: بالای راست صفحه
Container(
  padding: EdgeInsets.fromLTRB(width/15, height/20, width/15, 0),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
      // دکمه Skip
      GestureDetector(onTap: _skipOnboarding, child: Text('Skip')),
      // انتخاب زبان
      LanguageSelector(),
    ],
  ),
)

صفحه Profile

// موقعیت: در بخش General Settings
_buildInfoTile(
  icon: SvgPicture.asset(Assets.icons.languageSquare.path),
  title: 'Language',
  trailing: LanguageSelector(),
),

🔍 عیب‌یابی

مشکلات متداول

1. Overlay خارج از صفحه

علت: positioning غلط
راه‌حل: بررسی محاسبات leftPosition و rightPosition

// اطمینان از عدم overflow
if (leftPosition + overlayWidth > screenWidth - 16) {
  leftPosition = screenWidth - overlayWidth - 16;
}

2. Asset پرچم نمایش داده نمی‌شود

علت: مسیر فایل اشتباه
راه‌حل: بررسی assets.gen.dart و مسیرهای فایل

// بررسی وجود فایل
child: _currentFlag.endsWith('.svg')
  ? SvgPicture.asset(_currentFlag)
  : Image.asset(_currentFlag),

3. Animation کار نمی‌کند

علت: AnimationController dispose نشده
راه‌حل:

@override
void dispose() {
  _animationController.dispose();
  super.dispose();
}

Debug Commands

// برای debug positioning
print('Target position: ${targetPosition.dx}, ${targetPosition.dy}');
print('Screen width: $screenWidth');
print('Overlay width: $overlayWidth');

🚀 بهبودهای آینده

1. Localization Integration

// اتصال به سیستم i18n Flutter
class LocalizationManager {
  static void changeLocale(BuildContext context, String languageCode) {
    // تغییر زبان کل اپ
  }
}

2. Theme Integration

// تغییر زبان همراه با تغییر direction
void _changeLanguage(String code) {
  final isRTL = ['ar', 'fa'].contains(code);
  // اعمال تغییرات theme
}

3. Network Integration

// دریافت متن‌ها از سرور
class LanguageService {
  Future<Map<String, String>> getTranslations(String languageCode) {
    // API call
  }
}

📞 پشتیبانی

برای مشکلات فنی یا پیشنهادات بهبود، با تیم توسعه تماس بگیرید.

نسخه مستندات: 1.0
آخرین بروزرسانی: 22 سپتامبر 2025
نگارنده: GitHub Copilot


این مستندات برای توسعه‌دهندگان اپلیکیشن LBA تهیه شده است.