feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9909d9b4c1
commit
4d8414c96b
@@ -0,0 +1,433 @@
|
||||
import 'dart:math' as math;
|
||||
import 'package:animated_text_kit/animated_text_kit.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:siro_rider/constant/box_name.dart';
|
||||
import 'package:siro_rider/constant/colors.dart';
|
||||
import 'package:siro_rider/constant/style.dart';
|
||||
import 'package:siro_rider/main.dart';
|
||||
|
||||
import 'controller/home/splash_screen_controlle.dart';
|
||||
|
||||
class SplashScreen extends StatelessWidget {
|
||||
const SplashScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = Get.put(SplashScreenController());
|
||||
final size = MediaQuery.of(context).size;
|
||||
final accent = AppColor.secondaryColorStatic;
|
||||
final gold = AppColor.gold;
|
||||
final bg = AppColor.primaryColor;
|
||||
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: bg,
|
||||
body: Stack(
|
||||
children: [
|
||||
// ── Animated gradient overlay ──
|
||||
Positioned.fill(
|
||||
child: AnimatedBuilder(
|
||||
animation: controller.glowAnimation,
|
||||
builder: (_, __) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
bg,
|
||||
Color.lerp(bg, accent.withOpacity(0.08), controller.glowAnimation.value)!,
|
||||
bg,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Top-right glow ──
|
||||
Positioned(
|
||||
top: -size.height * 0.14,
|
||||
right: -size.width * 0.18,
|
||||
child: Container(
|
||||
width: size.width * 0.75,
|
||||
height: size.width * 0.75,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: RadialGradient(
|
||||
colors: [
|
||||
accent.withOpacity(0.08),
|
||||
Colors.transparent,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Bottom-left glow ──
|
||||
Positioned(
|
||||
bottom: -size.height * 0.08,
|
||||
left: -size.width * 0.2,
|
||||
child: Container(
|
||||
width: size.width * 0.65,
|
||||
height: size.width * 0.65,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: RadialGradient(
|
||||
colors: [
|
||||
gold.withOpacity(0.05),
|
||||
Colors.transparent,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Subtle grid ──
|
||||
Positioned.fill(
|
||||
child: CustomPaint(
|
||||
painter: _GridPainter(color: accent.withOpacity(0.035)),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Main content ──
|
||||
Center(
|
||||
child: FadeTransition(
|
||||
opacity: controller.titleFadeAnimation,
|
||||
child: ScaleTransition(
|
||||
scale: controller.titleScaleAnimation,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 240,
|
||||
height: 240,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Outer ring
|
||||
AnimatedBuilder(
|
||||
animation: controller.orbitAnimation,
|
||||
builder: (_, __) => Transform.rotate(
|
||||
angle: controller.orbitAnimation.value *
|
||||
2 *
|
||||
math.pi,
|
||||
child: CustomPaint(
|
||||
painter: _OrbitalRingPainter(
|
||||
radius: 108,
|
||||
dotColor: accent,
|
||||
lineOpacity: 0.2,
|
||||
dotSize: 5,
|
||||
),
|
||||
size: const Size(240, 240),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Inner ring
|
||||
AnimatedBuilder(
|
||||
animation: controller.orbitAnimation,
|
||||
builder: (_, __) => Transform.rotate(
|
||||
angle: -controller.orbitAnimation.value *
|
||||
2 *
|
||||
math.pi *
|
||||
0.65,
|
||||
child: CustomPaint(
|
||||
painter: _OrbitalRingPainter(
|
||||
radius: 76,
|
||||
dotColor: gold,
|
||||
lineOpacity: 0.14,
|
||||
dotSize: 4,
|
||||
dashCount: 16,
|
||||
),
|
||||
size: const Size(240, 240),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Center glow
|
||||
AnimatedBuilder(
|
||||
animation: controller.glowAnimation,
|
||||
builder: (_, __) => Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: accent.withOpacity(0.1 +
|
||||
controller.glowAnimation.value *
|
||||
0.18),
|
||||
blurRadius: 30 +
|
||||
controller.glowAnimation.value * 25,
|
||||
spreadRadius: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Siro text
|
||||
AnimatedTextKit(
|
||||
animatedTexts: [
|
||||
ColorizeAnimatedText(
|
||||
'Siro',
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 40,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: 5,
|
||||
height: 1,
|
||||
),
|
||||
colors: [
|
||||
Colors.white,
|
||||
accent,
|
||||
gold.withOpacity(0.85),
|
||||
Colors.white,
|
||||
],
|
||||
speed: const Duration(milliseconds: 500),
|
||||
),
|
||||
],
|
||||
isRepeatingAnimation: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
// Tagline
|
||||
FadeTransition(
|
||||
opacity: controller.taglineFadeAnimation,
|
||||
child: SlideTransition(
|
||||
position: controller.taglineSlideAnimation,
|
||||
child: Column(
|
||||
children: [
|
||||
_TaglineBadge(
|
||||
controller: controller, accent: accent),
|
||||
const SizedBox(height: 14),
|
||||
Text(
|
||||
'Your Journey Begins Here'.tr,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withOpacity(0.4),
|
||||
fontSize: 13,
|
||||
letterSpacing: 1,
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ── Bottom ──
|
||||
Positioned(
|
||||
left: 32,
|
||||
right: 32,
|
||||
bottom: 48,
|
||||
child: FadeTransition(
|
||||
opacity: controller.footerFadeAnimation,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Obx(() => _GlowProgressBar(
|
||||
value: controller.progress.value, accent: accent)),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('SIRO',
|
||||
style: TextStyle(
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.white.withOpacity(0.12),
|
||||
letterSpacing: 4.5)),
|
||||
Text('v${box.read(BoxName.packagInfo) ?? '1.0.0'}',
|
||||
style: TextStyle(
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white.withOpacity(0.12),
|
||||
letterSpacing: 1.5)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tagline badge ──
|
||||
class _TaglineBadge extends StatelessWidget {
|
||||
final SplashScreenController controller;
|
||||
final Color accent;
|
||||
const _TaglineBadge({required this.controller, required this.accent});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: accent.withOpacity(0.25), width: 1),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: accent.withOpacity(0.05),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
AnimatedBuilder(
|
||||
animation: controller.glowAnimation,
|
||||
builder: (_, __) => Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: accent
|
||||
.withOpacity(0.4 + controller.glowAnimation.value * 0.6),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: accent
|
||||
.withOpacity(controller.glowAnimation.value * 0.5),
|
||||
blurRadius: 6,
|
||||
spreadRadius: 1),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text('AI-Powered Mobility',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: accent.withOpacity(0.85),
|
||||
letterSpacing: 1.4)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Progress bar ──
|
||||
class _GlowProgressBar extends StatelessWidget {
|
||||
final double value;
|
||||
final Color accent;
|
||||
const _GlowProgressBar({required this.value, required this.accent});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 2,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.06),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
FractionallySizedBox(
|
||||
widthFactor: value.clamp(0.0, 1.0),
|
||||
child: Container(
|
||||
height: 2,
|
||||
decoration: BoxDecoration(
|
||||
gradient:
|
||||
LinearGradient(colors: [accent.withOpacity(0.5), accent]),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: accent.withOpacity(0.4),
|
||||
blurRadius: 8,
|
||||
spreadRadius: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Grid painter ──
|
||||
class _GridPainter extends CustomPainter {
|
||||
final Color color;
|
||||
_GridPainter({required this.color});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = color
|
||||
..strokeWidth = 0.5;
|
||||
const step = 36.0;
|
||||
for (double y = 0; y < size.height; y += step) {
|
||||
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
|
||||
}
|
||||
for (double x = 0; x < size.width; x += step) {
|
||||
canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_GridPainter old) => old.color != color;
|
||||
}
|
||||
|
||||
// ── Orbital ring ──
|
||||
class _OrbitalRingPainter extends CustomPainter {
|
||||
final double radius;
|
||||
final Color dotColor;
|
||||
final double lineOpacity;
|
||||
final double dotSize;
|
||||
final int dashCount;
|
||||
|
||||
const _OrbitalRingPainter({
|
||||
this.radius = 95,
|
||||
this.dotColor = const Color(0xFF8C9CF8),
|
||||
this.lineOpacity = 0.20,
|
||||
this.dotSize = 5.5,
|
||||
this.dashCount = 0,
|
||||
});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final center = Offset(size.width / 2, size.height / 2);
|
||||
|
||||
if (dashCount > 0) {
|
||||
final dashPaint = Paint()
|
||||
..color = dotColor.withOpacity(lineOpacity)
|
||||
..strokeWidth = 1
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round;
|
||||
for (int i = 0; i < dashCount; i++) {
|
||||
final start = i * (2 * math.pi / dashCount);
|
||||
final sweep = (2 * math.pi / dashCount) * 0.55;
|
||||
canvas.drawArc(Rect.fromCircle(center: center, radius: radius), start,
|
||||
sweep, false, dashPaint);
|
||||
}
|
||||
} else {
|
||||
final ringPaint = Paint()
|
||||
..color = dotColor.withOpacity(lineOpacity)
|
||||
..strokeWidth = 1
|
||||
..style = PaintingStyle.stroke;
|
||||
canvas.drawCircle(center, radius, ringPaint);
|
||||
}
|
||||
|
||||
final dotPos = Offset(center.dx, center.dy - radius);
|
||||
|
||||
final glowPaint = Paint()
|
||||
..color = dotColor.withOpacity(0.30)
|
||||
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 9);
|
||||
canvas.drawCircle(dotPos, dotSize + 2, glowPaint);
|
||||
|
||||
canvas.drawCircle(
|
||||
dotPos,
|
||||
dotSize,
|
||||
Paint()
|
||||
..color = dotColor
|
||||
..style = PaintingStyle.fill);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_OrbitalRingPainter old) => false;
|
||||
}
|
||||
Reference in New Issue
Block a user