Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8cedc50
removed un implemented features and solve github , fcm , and un seen …
asermohamed1 Nov 30, 2025
38297c9
fix
asermohamed1 Nov 30, 2025
4936b06
small fixes
asermohamed1 Nov 30, 2025
5ebe9d7
fixed the position and arrangement of chat
asermohamed1 Dec 3, 2025
2b49953
Update upload_media.dart
Hazem-Emam-404 Dec 4, 2025
2d64da5
update media
Hazem-Emam-404 Dec 4, 2025
cbe2400
some edits in tweet
yaraFarouk Dec 4, 2025
23e2ab7
Merge branch 'dev' into feature/timeline
yaraFarouk Dec 4, 2025
771c428
added localization setup and trends ui
kerloswagih Dec 5, 2025
1180c77
video done
yaraFarouk Dec 5, 2025
b2f7fe3
edit media in follower widget
Hazem-Emam-404 Dec 5, 2025
10ea8e8
Merge branch 'dev' into feature/profile
Hazem-Emam-404 Dec 5, 2025
b0fb525
fix some bugs
yaraFarouk Dec 5, 2025
b3f2960
Merge pull request #63 from CUFE-Software-Engineering-Project/feature…
Hazem-Emam-404 Dec 5, 2025
f22a427
Merge branch 'dev' into feature/profile
Hazem-Emam-404 Dec 5, 2025
04f4814
udate tweet widget and sidebar
Hazem-Emam-404 Dec 5, 2025
8242220
Merge pull request #62 from CUFE-Software-Engineering-Project/feature…
Hazem-Emam-404 Dec 5, 2025
6c493d6
modularize tweet widget
Hazem-Emam-404 Dec 5, 2025
4a72179
Merge branch 'dev' into feature/profile
Hazem-Emam-404 Dec 5, 2025
4adbaae
(fix) chat screen
asermohamed1 Dec 6, 2025
767b4b8
(feature) unseen count chat
asermohamed1 Dec 6, 2025
eee6d1b
feature of unseen count chats
asermohamed1 Dec 6, 2025
8da450a
initialize trends
Hazem-Emam-404 Dec 9, 2025
e3df3ad
Merge branch 'dev' into my-work
Hazem-Emam-404 Dec 10, 2025
31cade8
Merge pull request #64 from CUFE-Software-Engineering-Project/my-work
Hazem-Emam-404 Dec 10, 2025
2ae03f2
Merge pull request #67 from CUFE-Software-Engineering-Project/feature…
Hazem-Emam-404 Dec 10, 2025
41f96a5
updates in trends
Hazem-Emam-404 Dec 10, 2025
90cd0cc
fixed some auth ui
asermohamed1 Dec 10, 2025
528e3c3
Merge branch 'my-work' of https://github.com/CUFE-Software-Engineerin…
asermohamed1 Dec 10, 2025
8a067ed
trends update
Hazem-Emam-404 Dec 10, 2025
428a379
Update for_you_profile_tab.dart
Hazem-Emam-404 Dec 10, 2025
7f76869
Revert "Merge branch 'dev' into my-work"
Hazem-Emam-404 Dec 10, 2025
99afef1
fix
asermohamed1 Dec 10, 2025
c083ff8
fix
asermohamed1 Dec 10, 2025
aff7bc3
Merge branch 'my-work' of https://github.com/CUFE-Software-Engineerin…
asermohamed1 Dec 10, 2025
5fe20f1
Merge branch 'my-work' into feature/profile
Hazem-Emam-404 Dec 10, 2025
beb4bce
Revert "Merge branch 'my-work' into feature/profile"
Hazem-Emam-404 Dec 10, 2025
f45c005
fixes
Hazem-Emam-404 Dec 10, 2025
6e9c402
up to date with chat and auth
Hazem-Emam-404 Dec 10, 2025
74c1af7
update trends
Hazem-Emam-404 Dec 10, 2025
06bae4f
latest working notification and searching
TheMentorIo Dec 11, 2025
490491d
profile picture fixed
TheMentorIo Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
API_URL=http://node.shoy.publicvm.com/
API_URL=https://node.shoy.publicvm.com/
giphyApiKey=Ahjpgfo4LVqCACHRcwj0eoMlY5s7u1Uq
Socket_Url=https://app-dbef67eb-9a2e-44fa-abff-3e8b83204d9c.cleverapps.io
Socket_Url=https://node.shoy.publicvm.com
serverClientId=1096363232606-2fducjadk56bt4nsreqkj2jna7oiomga.apps.googleusercontent.com
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"cmake.sourceDirectory": "C:/Users/kerol/Cross_Platform/linux"
"cmake.sourceDirectory": "D:/ThirdYear/SWE/project/Cross_Platform/linux"
}
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
## Localization Setup

- Added `flutter_localizations` and `intl` to `pubspec.yaml`.
- Created `l10n.yaml` to configure Flutter's gen-l10n.
- Added ARB files in `lib/l10n/`:
- `app_en.arb`
- `app_ar.arb`
- Wired delegates and supported locales in `lib/main.dart`.

### How to add strings
- Edit ARB files under `lib/l10n/` and add new keys.
- Keep the same keys across languages.

### Generate localization code
- Run:

```powershell
flutter gen-l10n
```

- Import and use generated `AppLocalizations` in widgets:

```dart
import 'package:lite_x/l10n/app_localizations.dart';

Text(AppLocalizations.of(context)!.trendsTitle)
```

### Switching locales
- By default, the app supports `en` and `ar` and follows system locale.
- You can set a specific locale on `MaterialApp.router` by providing `locale: const Locale('ar')`.
# lite_x

Lite X is a Flutter/Riverpod client for the X-like backend that exposes a complete Tweets API surface. The app now exercises every Tweets Interaction endpoint (create/update/delete, likes, retweets, bookmarks, replies, quotes, mentions, summaries, liked tweets, user timelines, and search) through dedicated repositories, view models, and screens.
Expand Down
2 changes: 1 addition & 1 deletion firebase.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"litex-3c6f1","appId":"1:123824690535:android:fc6ea2d45764d44a960bc2","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"litex-3c6f1","configurations":{"android":"1:123824690535:android:fc6ea2d45764d44a960bc2","ios":"1:123824690535:ios:7d4e4fe266a006fe960bc2","macos":"1:123824690535:ios:7d4e4fe266a006fe960bc2","web":"1:123824690535:web:5c24b3d2f16411d1960bc2","windows":"1:123824690535:web:70728cc3cfda8de2960bc2"}}}}}}
{"flutter":{"platforms":{"android":{"default":{"projectId":"psychic-fin-474008-h8","appId":"1:112144721859:android:227c69fccfe2ec4c813f76","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"psychic-fin-474008-h8","configurations":{"android":"1:112144721859:android:227c69fccfe2ec4c813f76","ios":"1:112144721859:ios:990931c2c90bbd22813f76","macos":"1:112144721859:ios:990931c2c90bbd22813f76","web":"1:112144721859:web:cd55e199eb8ef04e813f76","windows":"1:112144721859:web:01d0e76c4bc65596813f76"}}}}}}
122 changes: 67 additions & 55 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
@@ -1,58 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Lite X</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>lite_x</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<!-- Photo / Camera / Microphone permissions -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow access to your photo library to select and upload images.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Allow the app to save photos to your photo library.</string>
<key>NSCameraUsageDescription</key>
<string>Allow access to the camera to take profile photos and capture media.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Allow access to the microphone to record audio for media uploads.</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Lite X</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>lite_x</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true />
<key>NSPhotoLibraryUsageDescription</key>
<string>Pick an image from gallery</string>
<key>NSCameraUsageDescription</key>
<string>Pick an image from Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>enable microphone</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true />
<key>UIApplicationSupportsIndirectInputEvents</key>
<true />
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.Artemsia.lite-x</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
<key>FlutterDeepLinkingEnabled</key>
<false />
</dict>
</plist>
8 changes: 8 additions & 0 deletions l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Flutter localization configuration
# See: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations
nullable-getter: false
untranslated-messages-file: build/untranslated_messages.txt
18 changes: 18 additions & 0 deletions lib/core/classes/PickedImage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,21 @@ Future<List<PickedImage>> pickImages({int maxImages = 4}) async {
return [];
}
}

Future<PickedImage?> pickVideo() async {
try {
final ImagePicker picker = ImagePicker();
final XFile? video = await picker.pickVideo(source: ImageSource.gallery);

if (video != null) {
return PickedImage(
file: File(video.path),
name: video.name,
path: video.path,
);
}
return null;
} catch (e) {
return null;
}
}
4 changes: 2 additions & 2 deletions lib/core/models/usermodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserModel {
final String username;

@HiveField(4)
final String? photo;
final String? photo; // media Id

@HiveField(5)
final String? bio;
Expand All @@ -40,7 +40,7 @@ class UserModel {
@HiveField(10)
final Set<String> interests;
@HiveField(11)
final String? localProfilePhotoPath;
final String? localProfilePhotoPath; // path of local profile photo

UserModel({
required this.name,
Expand Down
3 changes: 3 additions & 0 deletions lib/core/providers/unseenChatsCountProvider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'package:flutter_riverpod/legacy.dart';

final unseenChatsCountProvider = StateProvider<int>((ref) => 0);
67 changes: 31 additions & 36 deletions lib/core/routes/AppRouter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import 'package:lite_x/features/auth/view/screens/Create_Account/Password_Screen
import 'package:lite_x/features/auth/view/screens/Create_Account/Upload_Profile_Photo_Screen.dart';
import 'package:lite_x/features/auth/view/screens/Create_Account/Verification_Screen.dart';
import 'package:lite_x/features/auth/view/screens/Log_In/VerificationForgot_Screen.dart';
import 'package:lite_x/features/chat/view/screens/Search_Direct_messages.dart';
import 'package:lite_x/features/auth/view/screens/Oauth/SetBirthdate.dart';
import 'package:lite_x/features/chat/view/screens/Search_User_Group.dart';
import 'package:lite_x/features/chat/view/screens/chat_Screen.dart';
import 'package:lite_x/features/chat/view/screens/conversations_screen.dart';
import 'package:lite_x/features/explore/view/explore_screen.dart';
import 'package:lite_x/features/trends/view/screens/trends_screen.dart';
import 'package:lite_x/features/home/view/screens/tweet_screen.dart';
import 'package:lite_x/features/profile/models/profile_model.dart';
import 'package:lite_x/features/profile/models/shared.dart';
Expand Down Expand Up @@ -51,36 +52,12 @@ import 'package:lite_x/features/settings/screens/UserName_Screen.dart';
import 'package:lite_x/features/settings/screens/YourAccount_Screen.dart';
import 'package:lite_x/features/settings/screens/AccountInformation_Screen.dart';
import 'package:lite_x/features/settings/screens/ChangePassword_Screen.dart';
import 'package:lite_x/features/notifications/view/screens/Notification_Screen.dart';

class Approuter {
static final GoRouter router = GoRouter(
// initialLocation: "/appshell",
initialLocation: "/splash",
// initialExtra: ProfileModel(
// id: "",
// username: "hazememam",
// displayName: "Hazem Emam",
// email: "hazem@gmail.com",
// bio: "Hello from hazem emam ",
// avatarUrl:
// "https://images.pexels.com/photos/31510092/pexels-photo-31510092.jpeg",
// bannerUrl:
// "https://images.pexels.com/photos/1765033/pexels-photo-1765033.jpeg",
// followersCount: 15,
// followingCount: 20,
// tweetsCount: 15,
// isVerified: false,
// joinedDate: formatDate(DateTime(2004, 8, 21), DateFormatType.fullDate),
// website: "https://google.cof",
// location: "cairo",
// postCount: 2,
// birthDate: formatDate(DateTime(2004, 8, 21), DateFormatType.fullDate),
// isFollowing: false,
// isFollower: false,
// protectedAccount: false,
// isBlockedByMe: true,
// isMutedByMe: false,
// ),
// initialLocation: "/trends",
routes: [
GoRoute(
name: RouteConstants.splash,
Expand Down Expand Up @@ -184,6 +161,14 @@ class Approuter {
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.setbirthdate,
path: "/setbirthdate",
pageBuilder: (context, state) => CustomTransitionPage(
child: const Setbirthdate(),
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.ForgotpasswordScreen,
path: "/ForgotpasswordScreen",
Expand Down Expand Up @@ -279,14 +264,6 @@ class Approuter {
),
),

GoRoute(
name: RouteConstants.SearchDirectMessages,
path: "/SearchDirectMessages",
pageBuilder: (context, state) => CustomTransitionPage(
child: const SearchDirectMessages(),
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.Interests,
path: "/Interests",
Expand Down Expand Up @@ -366,6 +343,8 @@ class Approuter {
subtitle: extraData['subtitle'],
profileImage: extraData['avatarUrl'],
isGroup: extraData['isGroup'] ?? false,
recipientFollowersCount:
extraData['recipientFollowersCount'] ?? 0,
),
transitionsBuilder: _slideRightTransitionBuilder,
);
Expand All @@ -385,7 +364,7 @@ class Approuter {
name: RouteConstants.SearchScreen,
path: "/searchScreen",
pageBuilder: (context, state) => CustomTransitionPage(
child: SearchScreen(),
child: SearchScreen(extra: state.extra as Map<String, dynamic>?),
transitionsBuilder: _slideRightTransitionBuilder,
),
),
Expand All @@ -397,6 +376,14 @@ class Approuter {
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.TrendsScreen,
path: "/trends",
pageBuilder: (context, state) => CustomTransitionPage(
child: const TrendsScreen(),
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.ProfilePhotoScreen,
path: "/profilePhotoScreen",
Expand Down Expand Up @@ -453,6 +440,14 @@ class Approuter {
transitionsBuilder: _slideRightTransitionBuilder,
),
),
GoRoute(
name: RouteConstants.notifications,
path: "/notifications",
pageBuilder: (context, state) => CustomTransitionPage(
child: const NotificationScreen(),
transitionsBuilder: _slideRightTransitionBuilder,
),
),
],
redirect: (context, state) {
return null;
Expand Down
9 changes: 8 additions & 1 deletion lib/core/routes/Route_Constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class RouteConstants {
static String changePasswordScreen = "changePasswordScreen";
static String Interests = "Interests";
static String usernamesettings = "usernamesettings";
static String setbirthdate = "setbirthdate";

static String FollowingFollowersScreen = "FollowingFollowersScreen";
static String BirthDateScreen = "BirthDateScreen";
Expand All @@ -45,11 +46,17 @@ class RouteConstants {
"VerifyChangeEmailProfileScreen";

// search feature
static String SearchScreen = "SearchScreen";
static String SearchScreen = "searchScreen";

// explore feature
static String ExploreScreen = "ExploreScreen";
static String ExploreProfileScreen = "ExploreProfileScreen";


// trends feature
static String TrendsScreen = "TrendsScreen";


static String TweetDetailsScreen = "TweetDetailsScreen";
static String notifications = "notifications";
}
1 change: 0 additions & 1 deletion lib/core/services/deep_link_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class DeepLinkService {
}
});

// إضافة مراقب لحالة التطبيق
WidgetsBinding.instance.addObserver(_observer);
}

Expand Down
Loading
Loading