diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e69de29..3507709 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -0,0 +1,333 @@
+# `Contributing Guidelines`
+
+This documentation contains a set of guidelines to help you during the contribution process.
+
+We are happy to welcome all the contributions from anyone willing to improve/add new scripts to this project. Thank you for helping out and remember, **no contribution is too small.**
+
+[`Code of Conduct`](CODE_OF_CONDUCT.md)
+---------------
+
+
+
+```css
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+nkr.nikhil.nkr@gmail.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
+
+```
+
+
+
+----------
+
+### Before contributing please ensure your **pull request** adheres to the following guidelines
+
+## STEP-0 : Key Points to remember
+
+- Look at the [previous](https://github.com/nixrajput/social-media-app-flutter) work and get some idea from them.
+- Always maintain project folder architecture.
+- Don't delete/remove any existing file or folder.
+- Please don't add any License under your work. This repo already under `GPL-3.0 License`.
+
+## STEP-1 : **Flow**
+
+### `Tree of Index`
+
+```js
+.
+├── src
+│ ├── config
+│ │ ├── config.env
+│ │
+│ ├── constants
+│ │ ├── responseMessages.js
+| |
+│ ├── helpers
+│ │ ├── catchAsyncError.js
+│ │ ├── errorHandler.js
+│ │
+│ ├── middlewares
+│ │ ├── auth.js
+│ │ ├── error.js
+│ │ ├── multer.js
+| |
+│ ├── models
+| | ├── index.js
+│ │ ├── comment
+│ │ │ ├── comment.js
+│ │ │
+│ │ ├── device-info
+│ │ │ ├── deviceInfo.js
+│ │ │
+│ │ ├── post
+│ │ │ ├── post.js
+│ │ │
+│ │ ├── user
+│ │ │ ├── user.js
+│ │ │
+│ │ ├── notification
+│ │ │ ├── notification.js
+│ │ │
+│ │ ├── otp
+│ │ │ ├── otp.js
+│ │ │
+│ │ ├── hashtag
+│ │ │ ├── hashtag.js
+│ │ │
+│ │ ├── report
+│ │ │ ├── report.js
+│ │
+│ ├── modules
+│ │ ├── auth
+│ │ │ ├── index.js
+│ │ │ ├── controllers
+│ │ │ │ ├── index.js
+│ │ │ │ ├── forgot-password
+│ │ │ │ │ ├── forgotPassword.js
+│ │ │ │ │
+│ │ │ │ ├── login
+│ │ │ │ │ ├── login.js
+│ │ │ │ │
+│ │ │ │ ├── logout
+│ │ │ │ │ ├── logout.js
+│ │ │ │ │
+│ │ │ │ ├── register
+│ │ │ │ │ ├── register.js
+│ │ │ │ │
+│ │ │ │ ├── reset-password
+│ │ │ │ │ ├── resetPassword.js
+│ │ │ │ │
+│ │ │ │ ├── verify-account
+│ │ │ │ │ ├── verifyAccount.js
+│ │ │ │ │ ├── verifyAccountOtp.js
+│ │ │ │ │
+│ │ │ │
+│ │ │ ├── routes
+│ │ │ │ ├── index.js
+│ │ │
+│ │ │
+│ │ ├── admin
+│ │ │ ├── index.js
+│ │ │ ├── controllers
+│ │ │ │ ├── index.js
+│ │ │ │ ├── user
+│ │ │ │ │ ├── deleteUser.js
+│ │ │ │ │ ├── getAllUsers.js
+│ │ │ │ │ ├── getUserDetails.js
+│ │ │ │ │ ├── updateUser.js
+│ │ │ │ │ ├── updateUserRole.js
+│ │ │ │ │ ├── searchUser.js
+│ │ │ │ │ ├── updateAccountStatus.js
+│ │ │ │ │ ├── updateVerificationStatus.js
+│ │ │ │ │
+│ │ │ │ ├── post
+│ │ │ │ │ ├── deletePost.js
+│ │ │ │ │ ├── getAllPosts.js
+│ │ │ │ │ ├── getPostDetails.js
+│ │ │ │ │ ├── updatePost.js
+│ │ │ │ │ ├── updatePostStatus.js
+│ │ │ │ │ ├── searchPost.js
+│ │ │ │
+│ │ │ ├── routes
+│ │ │ │ ├── index.js
+│ │ │
+│ │ ├── user
+|
+├── .gitignore
+|
+├── CODE_OF_CONDUCT.md
+|
+├── CONTRIBUTING.md
+|
+├── LICENSE.md
+|
+├── package.json
+|
+├── package-lock.yaml
+|
+└── README.md
+```
+
+## STEP-2 : `Contributing`
+
+We'd love your contributions! Kindly follow the steps below to get started:
+
+0. Star this repository.
+
+1. Fork this repository.
+
+2. Clone the forked repository.
+
+```css
+git clone https://github.com//social-media-app-flutter
+```
+
+3. Create a new branch.
+
+```css
+git checkout -b
+```
+
+4. Make changes.
+
+5. Stage your changes and commit
+
+```css
+git add -A
+
+git commit -m ""
+```
+
+6. Push your local commits to the remote repo.
+
+```css
+git push -u origin
+```
+
+7. Create a Pull-Request .
+
+8. Congratulations! 🎉 Sit and relax, you've made your contribution to Rippl! - A Social Media App . ✌️ ❤️ 💥
+
+## **Note**
+
+- New categories, or improvements to the existing categorisation, are always welcome.
+- If you have any idea or suggestions then check this [Discussion Tab](https://github.com/nixrajput/social-media-app-flutter/discussions). and put your [idea](https://github.com/nixrajput/social-media-app-flutter/discussions/categories/ideas) or [suggestions](https://github.com/nixrajput/social-media-app-flutter/discussions/categories/ideas)🏆
+
+### [`Welcome to Discussions!`](https://github.com/nixrajput/social-media-app-flutter/discussions)
+
+[Discussion Tab](https://github.com/nixrajput/social-media-app-flutter/discussions)
+
+## Need more help?🤔
+
+You can refer to the following articles on basics of Git and Github and also contact the Project [Admin](https://github.com/nixrajput), in case you are stuck:
+
+- [Forking a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)
+- [Cloning a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-an-issue-or-pull-request)
+- [How to create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github)
+- [Getting started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6)
+- [Learn GitHub from Scratch](https://www.youtube.com/watch?v=BCQHnlnPusY&list=PLozRqGzj97d02YjR5JVqDwN2K0cAiT7VK)
diff --git a/android/app/src/main/res/drawable-night-v21/background.png b/android/app/src/main/res/drawable-night-v21/background.png
index 0d2a8da..87a950a 100644
Binary files a/android/app/src/main/res/drawable-night-v21/background.png and b/android/app/src/main/res/drawable-night-v21/background.png differ
diff --git a/android/app/src/main/res/drawable-night/background.png b/android/app/src/main/res/drawable-night/background.png
index 0d2a8da..87a950a 100644
Binary files a/android/app/src/main/res/drawable-night/background.png and b/android/app/src/main/res/drawable-night/background.png differ
diff --git a/android/app/src/main/res/drawable-v21/background.png b/android/app/src/main/res/drawable-v21/background.png
index 028ee6f..8c43167 100644
Binary files a/android/app/src/main/res/drawable-v21/background.png and b/android/app/src/main/res/drawable-v21/background.png differ
diff --git a/android/app/src/main/res/drawable/background.png b/android/app/src/main/res/drawable/background.png
index 028ee6f..8c43167 100644
Binary files a/android/app/src/main/res/drawable/background.png and b/android/app/src/main/res/drawable/background.png differ
diff --git a/flutter_native_splash.yaml b/flutter_native_splash.yaml
index 4315a5a..a5f551a 100644
--- a/flutter_native_splash.yaml
+++ b/flutter_native_splash.yaml
@@ -3,11 +3,11 @@ flutter_native_splash:
# flutter pub run flutter_native_splash:remove
#background_image: 'assets/images/splash.png'
- color: "#F0F0F0"
+ color: "#ECECEC"
image: "assets/images/logo_trans.png"
#background_image_dark: "assets/dark-background.png"
- color_dark: "#1C1D31"
+ color_dark: "#12121E"
image_dark: "assets/images/logo_trans.png"
fullscreen: true
\ No newline at end of file
diff --git a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
index 028ee6f..8c43167 100644
Binary files a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png and b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png
index 0d2a8da..87a950a 100644
Binary files a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png and b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png differ
diff --git a/lib/apis/models/entities/phone.dart b/lib/apis/models/entities/phone.dart
deleted file mode 100644
index 9f23e1c..0000000
--- a/lib/apis/models/entities/phone.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-import 'package:equatable/equatable.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-part 'phone.g.dart';
-
-@JsonSerializable()
-class Phone extends Equatable {
- const Phone({
- this.countryCode,
- this.phoneNo,
- });
-
- factory Phone.fromJson(Map json) => _$PhoneFromJson(json);
-
- Map toJson() => _$PhoneToJson(this);
-
- @JsonKey(name: 'countryCode')
- final String? countryCode;
-
- @JsonKey(name: 'phoneNo')
- final String? phoneNo;
-
- @override
- List get props => [
- countryCode,
- phoneNo,
- ];
-}
diff --git a/lib/apis/models/entities/phone.g.dart b/lib/apis/models/entities/phone.g.dart
deleted file mode 100644
index 28029ce..0000000
--- a/lib/apis/models/entities/phone.g.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'phone.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Phone _$PhoneFromJson(Map json) => Phone(
- countryCode: json['countryCode'] as String?,
- phoneNo: json['phoneNo'] as String?,
- );
-
-Map _$PhoneToJson(Phone instance) => {
- 'countryCode': instance.countryCode,
- 'phoneNo': instance.phoneNo,
- };
diff --git a/lib/apis/models/entities/profile.dart b/lib/apis/models/entities/profile.dart
index 2fa7f53..807bac5 100644
--- a/lib/apis/models/entities/profile.dart
+++ b/lib/apis/models/entities/profile.dart
@@ -1,6 +1,5 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:social_media_app/apis/models/entities/media_file.dart';
-import 'package:social_media_app/apis/models/entities/phone.dart';
part 'profile.g.dart';
@@ -15,7 +14,8 @@ class Profile {
required this.uname,
this.avatar,
this.phone,
- required this.phoneVerified,
+ this.countryCode,
+ this.phoneVerified,
this.gender,
this.dob,
this.about,
@@ -40,7 +40,7 @@ class Profile {
Map toJson() => _$ProfileToJson(this);
@JsonKey(name: '_id')
- final String id;
+ String id;
@JsonKey(name: 'fname')
String fname;
@@ -58,13 +58,16 @@ class Profile {
String uname;
@JsonKey(name: 'avatar')
- final MediaFile? avatar;
+ MediaFile? avatar;
@JsonKey(name: 'phone')
- Phone? phone;
+ String? phone;
+
+ @JsonKey(name: 'countryCode')
+ String? countryCode;
@JsonKey(name: 'phoneVerified')
- bool phoneVerified;
+ bool? phoneVerified;
@JsonKey(name: 'gender')
String? gender;
@@ -79,7 +82,7 @@ class Profile {
String? profession;
@JsonKey(name: 'location')
- final String? location;
+ String? location;
@JsonKey(name: 'website')
String? website;
@@ -94,7 +97,7 @@ class Profile {
int followingCount;
@JsonKey(name: 'role')
- final String role;
+ String role;
@JsonKey(name: 'accountPrivacy')
String accountPrivacy;
@@ -112,5 +115,5 @@ class Profile {
bool isVerified;
@JsonKey(name: 'createdAt')
- final DateTime createdAt;
+ DateTime createdAt;
}
diff --git a/lib/apis/models/entities/profile.g.dart b/lib/apis/models/entities/profile.g.dart
index cf3b01a..0e95a57 100644
--- a/lib/apis/models/entities/profile.g.dart
+++ b/lib/apis/models/entities/profile.g.dart
@@ -16,10 +16,9 @@ Profile _$ProfileFromJson(Map json) => Profile(
avatar: json['avatar'] == null
? null
: MediaFile.fromJson(json['avatar'] as Map),
- phone: json['phone'] == null
- ? null
- : Phone.fromJson(json['phone'] as Map),
- phoneVerified: json['phoneVerified'] as bool,
+ phone: json['phone'] as String?,
+ countryCode: json['countryCode'] as String?,
+ phoneVerified: json['phoneVerified'] as bool?,
gender: json['gender'] as String?,
dob: json['dob'] as String?,
about: json['about'] as String?,
@@ -47,6 +46,7 @@ Map _$ProfileToJson(Profile instance) => {
'uname': instance.uname,
'avatar': instance.avatar,
'phone': instance.phone,
+ 'countryCode': instance.countryCode,
'phoneVerified': instance.phoneVerified,
'gender': instance.gender,
'dob': instance.dob,
diff --git a/lib/apis/providers/api_provider.dart b/lib/apis/providers/api_provider.dart
index ba07df1..8d74f11 100644
--- a/lib/apis/providers/api_provider.dart
+++ b/lib/apis/providers/api_provider.dart
@@ -87,6 +87,18 @@ class ApiProvider {
return response;
}
+ Future validateToken(String token) async {
+ final response = await _client.get(
+ Uri.parse('${baseUrl!}${AppUrls.validateTokenEndpoint}?token=$token'),
+ headers: {
+ "content-type": "application/json",
+ "authorization": "Bearer $token",
+ },
+ );
+
+ return response;
+ }
+
/// Location Info ------------------------------------------------------------
Future getLocationInfo() async {
@@ -175,26 +187,78 @@ class ApiProvider {
return response;
}
- Future sendEmailVerificationOtp(String token) async {
- final response = await _client.get(
- Uri.parse(baseUrl! + AppUrls.verifyEmailEndpoint),
+ Future sendChangeEmailOtp(
+ String token,
+ Map body,
+ ) async {
+ final response = await _client.post(
+ Uri.parse(baseUrl! + AppUrls.changeEmailEndpoint),
+ headers: {
+ "content-type": "application/json",
+ "authorization": "Bearer $token",
+ },
+ body: jsonEncode(body),
+ );
+
+ return response;
+ }
+
+ Future changeEmail(
+ String token,
+ Map body,
+ ) async {
+ final response = await _client.put(
+ Uri.parse(baseUrl! + AppUrls.changeEmailEndpoint),
headers: {
"content-type": "application/json",
"authorization": "Bearer $token",
},
+ body: jsonEncode(body),
+ );
+
+ return response;
+ }
+
+ Future sendAddChangePhoneOtp(
+ String token,
+ Map body,
+ ) async {
+ final response = await _client.post(
+ Uri.parse(baseUrl! + AppUrls.addChangePhoneEndpoint),
+ headers: {
+ "content-type": "application/json",
+ "authorization": "Bearer $token",
+ },
+ body: jsonEncode(body),
+ );
+
+ return response;
+ }
+
+ Future addChangePhone(
+ String token,
+ Map body,
+ ) async {
+ final response = await _client.put(
+ Uri.parse(baseUrl! + AppUrls.addChangePhoneEndpoint),
+ headers: {
+ "content-type": "application/json",
+ "authorization": "Bearer $token",
+ },
+ body: jsonEncode(body),
);
return response;
}
- Future verifyEmail(String token, String otp) async {
+ Future verifyPassword(String token, String password) async {
final response = await _client.post(
- Uri.parse(baseUrl! + AppUrls.verifyEmailEndpoint),
+ Uri.parse(baseUrl! + AppUrls.verifyPasswordEndpoint),
headers: {
"content-type": "application/json",
"authorization": "Bearer $token",
},
- body: jsonEncode({'otp': otp}),
+ body: jsonEncode({"password": password}),
);
return response;
diff --git a/lib/apis/services/auth_service.dart b/lib/apis/services/auth_service.dart
index 5804e0c..d43d793 100644
--- a/lib/apis/services/auth_service.dart
+++ b/lib/apis/services/auth_service.dart
@@ -53,6 +53,41 @@ class AuthService extends GetxService {
return token;
}
+ Future _validateToken(String token) async {
+ var isValid = true;
+ try {
+ final response = await _apiProvider.validateToken(token);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ AppUtils.printLog(decodedData);
+
+ if (response.statusCode == 200) {
+ AppUtils.printLog(decodedData[StringValues.message]);
+ } else {
+ isValid = false;
+ AppUtils.printLog(decodedData[StringValues.message]);
+ await AppUtils.clearLoginDataFromLocalStorage();
+ }
+ } on SocketException {
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+
+ return isValid;
+ }
+
Future _logout(bool showLoading) async {
AppUtils.printLog("Logout Request");
if (showLoading) AppUtils.showLoadingDialog();
@@ -121,13 +156,12 @@ class AuthService extends GetxService {
if (response.statusCode == 200) {
locationInfo = LocationInfo.fromJson(decodedData);
} else {
- AppUtils.printLog(StringValues.message);
+ AppUtils.printLog(decodedData[StringValues.message]);
}
} on SocketException {
AppUtils.printLog(StringValues.internetConnError);
AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
} on TimeoutException {
- AppUtils.printLog(StringValues.connTimedOut);
AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
@@ -176,7 +210,6 @@ class AuthService extends GetxService {
} on TimeoutException {
AppUtils.printLog("Save LoginInfo Error");
AppUtils.printLog(StringValues.connTimedOut);
- AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
AppUtils.printLog("Save LoginInfo Error");
@@ -218,6 +251,8 @@ class AuthService extends GetxService {
Future logout({showLoading = false}) async =>
await _logout(showLoading);
+ Future validateToken(String token) async => await _validateToken(token);
+
@override
void onInit() {
_checkForInternetConnectivity();
diff --git a/lib/apis/services/theme_controller.dart b/lib/apis/services/theme_controller.dart
index 38ac310..d7f142f 100644
--- a/lib/apis/services/theme_controller.dart
+++ b/lib/apis/services/theme_controller.dart
@@ -1,36 +1,53 @@
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/helpers/utils.dart';
-const appThemeModes = {
- StringValues.system,
- StringValues.light,
- StringValues.dark,
-};
+enum AppThemeModes {
+ system,
+ light,
+ dark,
+}
class AppThemeController extends GetxController {
+ static AppThemeController get find => Get.find();
final themeData = GetStorage();
- final _themeMode = Rx(appThemeModes.first);
+ final _themeMode = Rx(AppThemeModes.system);
- String get themeMode => _themeMode.value;
+ AppThemeModes get themeMode => _themeMode.value;
@override
void onInit() {
- themeData.writeIfNull(StringValues.themeMode, appThemeModes.first);
+ themeData.writeIfNull(StringValues.themeMode, 'system');
getThemeMode();
super.onInit();
}
- void setThemeMode(value) {
+ void setThemeMode(AppThemeModes value) {
_themeMode(value);
- themeData.write(StringValues.themeMode, value);
+ if (value == AppThemeModes.light) {
+ themeData.write(StringValues.themeMode, 'light');
+ } else if (value == AppThemeModes.dark) {
+ themeData.write(StringValues.themeMode, 'dark');
+ } else {
+ themeData.write(StringValues.themeMode, 'system');
+ }
+ AppUtils.printLog('changed to ${_themeMode.value}');
update();
}
- void getThemeMode() {
- String themeMode = themeData.read(StringValues.themeMode);
- _themeMode(themeMode);
+ void getThemeMode() async {
+ String themeMode = await themeData.read(StringValues.themeMode);
+ AppUtils.printLog('saved theme mode = $themeMode');
+ if (themeMode == 'light') {
+ _themeMode(AppThemeModes.light);
+ } else if (themeMode == 'dark') {
+ _themeMode(AppThemeModes.dark);
+ } else {
+ _themeMode(AppThemeModes.system);
+ }
+ AppUtils.printLog(_themeMode.value);
update();
}
}
diff --git a/lib/constants/colors.dart b/lib/constants/colors.dart
index 0e09d83..f110f3c 100644
--- a/lib/constants/colors.dart
+++ b/lib/constants/colors.dart
@@ -37,7 +37,7 @@ abstract class ColorValues {
static const Color lightBodyTextColor = Color(0xFF323232);
static const Color lightSubtitleTextColor = Color(0xFF737373);
- static const Color darkBodyTextColor = Color(0xFFE8E8E8);
+ static const Color darkBodyTextColor = Color(0xFFDCDCDC);
static const Color darkSubtitleTextColor = Color(0xFFA0A0A0);
static const Color lightBgColor = Color.fromRGBO(236, 236, 236, 1.0);
diff --git a/lib/constants/strings.dart b/lib/constants/strings.dart
index 13528bb..85183ee 100644
--- a/lib/constants/strings.dart
+++ b/lib/constants/strings.dart
@@ -28,6 +28,8 @@ abstract class StringValues {
static const resetYourPassword = 'Reset your password';
static const forgotYourPassword = 'Forgot your password?';
static const verifyYourAccount = 'Verify your account';
+ static const verifyPassword = 'Verify Password';
+ static const enterDifferentEmail = 'Enter an email other than current email';
static const enterEmailForOtp =
'Enter your email address and an OTP will be sent to your email address if account exists';
static const enterOtpYouGet =
@@ -55,12 +57,18 @@ abstract class StringValues {
static const enterOldPassword = 'Enter current password';
static const enterNewPassword = 'Enter a new password';
static const enterOtp = 'Enter the OTP';
+ static const enterWebsiteUrl = 'Enter your website URL';
static const enterConfirmPassword = 'Retype your password';
static const errorOccurred = 'An error occurred, please try again.';
static const unknownErrorOccurred = 'An unknown error occurred.';
- static const loginSuccessful = 'Logged in successfully.';
- static const registrationSuccessful = 'Registered successfully.';
+ static const loginSuccessful = 'Logged in successfully';
+ static const registrationSuccessful =
+ 'Account registered successfully, please verify your account';
static const logoutSuccessful = 'Logged out successfully.';
+ static const enterValidUrl = 'Enter a valid website URL';
+ static const enterPhoneNo = 'Enter a valid phone number';
+ static const enterDifferentPhoneNo =
+ 'Enter a phone number other than current phone number';
static const token = 'token';
static const expiresAt = 'expiresAt';
static const loginData = 'loginData';
@@ -178,6 +186,7 @@ abstract class StringValues {
static const sendUsSuggestions = 'Send us suggestions';
static const privacyPolicy = 'Privacy Policy';
static const termsOfUse = 'Terms of Use';
+ static const website = 'Website';
static const nameHelpText =
"Either your full name, nickname, or business name.";
static const accountSettingsHelp =
@@ -192,8 +201,10 @@ abstract class StringValues {
static const themeSettingsHelp = "Manage application theme modes.";
static const deactivateAccount = 'Deactivate Account';
static const downloadArchiveOfData = 'Download an archive of your data';
- static const changeEmail = 'Change Email address';
- static const changePhoneNo = 'Change Phone number';
+ static const changeEmailAddress = 'Change Email Address';
+ static const changeEmail = 'Change Email';
+ static const changePhoneNo = 'Change Phone Number';
+ static const changePhone = 'Change Phone';
static const verification = 'Verification';
static const applyForSelfVerify = 'Apply for self verification';
static const applyForBlueTick = 'Apply for blue tick';
@@ -203,6 +214,7 @@ abstract class StringValues {
'Help protect your account from unauthorised access by requiring a second authentication method in addition to your password.';
static const moreDetails = 'More Details';
static const websiteUrl = 'https://nixlab.co.in';
+ static const portfolioUrl = 'https://nixrajput.nixlab.co.in';
static const appDownloadUrl =
'https://github.com/nixrajput/social-media-app-flutter/releases';
static const appGithubUrl =
diff --git a/lib/constants/urls.dart b/lib/constants/urls.dart
index 12022be..651390e 100644
--- a/lib/constants/urls.dart
+++ b/lib/constants/urls.dart
@@ -29,8 +29,11 @@ abstract class AppUrls {
static const String updateProfileEndpoint = '/update-profile';
static const String checkUsernameEndpoint = '/check-username';
static const String changeUsernameEndpoint = '/change-username';
- static const String verifyEmailEndpoint = '/verify-email';
static const String deleteProfileEndpoint = '/delete-profile';
+ static const String validateTokenEndpoint = '/validate-token';
+ static const String addChangePhoneEndpoint = '/add-change-phone';
+ static const String changeEmailEndpoint = '/change-email';
+ static const String verifyPasswordEndpoint = '/verify-password';
static const String saveLoginInfoEndpoint = '/save-device-info';
static const String getLoginInfoEndpoint = '/get-device-info';
diff --git a/lib/global_widgets/custom_app_bar.dart b/lib/global_widgets/custom_app_bar.dart
index 07c3c8b..98534a6 100644
--- a/lib/global_widgets/custom_app_bar.dart
+++ b/lib/global_widgets/custom_app_bar.dart
@@ -31,43 +31,36 @@ class NxAppBar extends StatelessWidget {
return Container(
width: Dimens.screenWidth,
color: bgColor ?? Colors.transparent,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- mainAxisSize: MainAxisSize.min,
- children: [
- Padding(
- padding: padding ?? Dimens.edgeInsets8,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- if (showBackBtn == true)
- GestureDetector(
- onTap: RouteManagement.goToBack,
- child: Icon(
- CupertinoIcons.arrow_left,
- color: backBtnColor ??
- Theme.of(context).textTheme.bodyText1!.color,
- size: Dimens.twentyFour,
+ child: Padding(
+ padding: padding ?? Dimens.edgeInsets8,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ if (showBackBtn == true)
+ GestureDetector(
+ onTap: RouteManagement.goToBack,
+ child: Icon(
+ CupertinoIcons.arrow_left,
+ color: backBtnColor ??
+ Theme.of(context).textTheme.bodyText1!.color,
+ size: Dimens.twentyFour,
+ ),
+ ),
+ if (showBackBtn == true) Dimens.boxWidth16,
+ if (leading != null) leading!,
+ if (leading != null && title != null) Dimens.boxWidth16,
+ if (title != null && title!.isNotEmpty)
+ Text(
+ title!,
+ style: titleStyle ??
+ AppStyles.style20Bold.copyWith(
+ color: Theme.of(context).textTheme.bodyText1!.color,
+ height: 1.0,
),
- ),
- if (showBackBtn == true) Dimens.boxWidth16,
- if (leading != null) leading!,
- if (leading != null && title != null) Dimens.boxWidth16,
- if (title != null && title!.isNotEmpty)
- Text(
- title!,
- style: titleStyle ??
- AppStyles.style20Bold.copyWith(
- color: Theme.of(context).textTheme.bodyText1!.color,
- ),
- )
- ],
- ),
- ),
- if (showDivider == true) Dimens.divider,
- ],
+ )
+ ],
+ ),
),
);
}
diff --git a/lib/global_widgets/custom_list_tile.dart b/lib/global_widgets/custom_list_tile.dart
index a9c5e38..b00cf4a 100644
--- a/lib/global_widgets/custom_list_tile.dart
+++ b/lib/global_widgets/custom_list_tile.dart
@@ -37,7 +37,7 @@ class NxListTile extends StatelessWidget {
maxWidth: Dimens.screenWidth,
),
decoration: BoxDecoration(
- color: bgColor ?? Colors.transparent,
+ color: bgColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: borderRadius ?? BorderRadius.circular(Dimens.zero),
),
child: Row(
diff --git a/lib/global_widgets/primary_outlined_btn.dart b/lib/global_widgets/primary_outlined_btn.dart
index 13a7d1f..648b1bb 100644
--- a/lib/global_widgets/primary_outlined_btn.dart
+++ b/lib/global_widgets/primary_outlined_btn.dart
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
-import 'package:social_media_app/constants/colors.dart';
import 'package:social_media_app/constants/dimens.dart';
import 'package:social_media_app/constants/styles.dart';
@@ -55,7 +54,7 @@ class NxOutlinedButton extends StatelessWidget {
),
decoration: BoxDecoration(
border: Border.all(
- color: borderColor ?? ColorValues.primaryColor,
+ color: borderColor ?? Theme.of(context).textTheme.bodyText1!.color!,
width: borderWidth ?? Dimens.one * 1.5,
style: borderStyle ?? BorderStyle.solid,
),
@@ -73,7 +72,8 @@ class NxOutlinedButton extends StatelessWidget {
label,
style: labelStyle ??
AppStyles.style16Bold.copyWith(
- color: labelColor ?? ColorValues.primaryColor,
+ color: labelColor ??
+ Theme.of(context).textTheme.bodyText1!.color,
fontSize: fontSize ?? Dimens.sixTeen,
),
),
diff --git a/lib/helpers/get_time_ago_msg.dart b/lib/helpers/get_time_ago_msg.dart
new file mode 100644
index 0000000..fb5a2dd
--- /dev/null
+++ b/lib/helpers/get_time_ago_msg.dart
@@ -0,0 +1,33 @@
+import 'package:get_time_ago/get_time_ago.dart';
+
+class CustomMessages implements Messages {
+ @override
+ String prefixAgo() => '';
+
+ @override
+ String suffixAgo() => 'ago';
+
+ @override
+ String secsAgo(int seconds) => '${seconds}s';
+
+ @override
+ String minAgo(int minutes) => '1m';
+
+ @override
+ String minsAgo(int minutes) => '${minutes}m';
+
+ @override
+ String hourAgo(int minutes) => '1h';
+
+ @override
+ String hoursAgo(int hours) => '${hours}h';
+
+ @override
+ String dayAgo(int hours) => '1d';
+
+ @override
+ String daysAgo(int days) => '${days}d';
+
+ @override
+ String wordSeparator() => ' ';
+}
diff --git a/lib/helpers/validators.dart b/lib/helpers/validators.dart
new file mode 100644
index 0000000..afb9968
--- /dev/null
+++ b/lib/helpers/validators.dart
@@ -0,0 +1,13 @@
+abstract class Validators {
+ static const String urlPattern =
+ r"(https?|http)://([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:,.;]*)?";
+ static const String emailPattern = r'\S+@\S+';
+ static const String phonePattern = r'[\d-]{9,}';
+
+ static bool isValidUrl(String url) {
+ if (RegExp(urlPattern, caseSensitive: false).hasMatch(url)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
index 2cb57c8..eb08bb4 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -14,6 +14,7 @@ import 'package:social_media_app/modules/app_update/app_update_controller.dart';
import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
import 'package:social_media_app/modules/settings/controllers/login_device_info_controller.dart';
import 'package:social_media_app/routes/app_pages.dart';
+import 'package:social_media_app/translations/app_translations.dart';
void main() async {
try {
@@ -43,11 +44,13 @@ Future initServices() async {
await Get.find().getToken().then((value) async {
Get.find().autoLogout();
if (value.isNotEmpty) {
- var hasData = await Get.find().loadProfileDetails();
- if (hasData) {
- isLogin = true;
- } else {
- await Get.find().logout();
+ var tokenValid = await Get.find().validateToken(value);
+
+ if (tokenValid) {
+ var hasData = await Get.find().loadProfileDetails();
+ if (hasData) {
+ isLogin = true;
+ }
}
}
isLogin
@@ -72,6 +75,7 @@ class MyApp extends StatelessWidget {
systemNavigationBarIconBrightness: Brightness.dark,
),
);
+ //AppThemeController.find.setThemeMode(AppThemeModes.light);
} else {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
@@ -82,6 +86,7 @@ class MyApp extends StatelessWidget {
systemNavigationBarIconBrightness: Brightness.light,
),
);
+ //AppThemeController.find.setThemeMode(AppThemeModes.dark);
}
return GetBuilder(
@@ -95,16 +100,19 @@ class MyApp extends StatelessWidget {
darkTheme: AppThemes.darkTheme,
getPages: AppPages.pages,
initialRoute: isLogin ? AppRoutes.home : AppRoutes.welcome,
+ translations: AppTranslation(),
+ locale: Get.deviceLocale,
+ fallbackLocale: const Locale('en', 'US'),
),
),
);
}
- _handleAppTheme(mode) {
- if (mode == StringValues.dark) {
+ _handleAppTheme(AppThemeModes mode) {
+ if (mode == AppThemeModes.dark) {
return ThemeMode.dark;
}
- if (mode == StringValues.light) {
+ if (mode == AppThemeModes.light) {
return ThemeMode.light;
}
return ThemeMode.system;
diff --git a/lib/modules/auth/controllers/password_controller.dart b/lib/modules/auth/controllers/password_controller.dart
index f8405cd..b79adb5 100644
--- a/lib/modules/auth/controllers/password_controller.dart
+++ b/lib/modules/auth/controllers/password_controller.dart
@@ -93,7 +93,6 @@ class PasswordController extends GetxController {
_isLoading.value = false;
update();
AppUtils.printLog(StringValues.connTimedOut);
- AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
AppUtils.closeDialog();
@@ -186,7 +185,6 @@ class PasswordController extends GetxController {
_isLoading.value = false;
update();
AppUtils.printLog(StringValues.connTimedOut);
- AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
AppUtils.closeDialog();
diff --git a/lib/modules/auth/controllers/register_controller.dart b/lib/modules/auth/controllers/register_controller.dart
index ab63d09..609f477 100644
--- a/lib/modules/auth/controllers/register_controller.dart
+++ b/lib/modules/auth/controllers/register_controller.dart
@@ -113,7 +113,7 @@ class RegisterController extends GetxController {
'confirmPassword': confPassword,
};
- AppUtils.printLog("User Registration Request...");
+ AppUtils.printLog("User Registration Request");
AppUtils.showLoadingDialog();
_isLoading.value = true;
update();
@@ -128,15 +128,18 @@ class RegisterController extends GetxController {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("User Registration Success");
AppUtils.showSnackBar(
StringValues.registrationSuccessful,
StringValues.success,
);
- RouteManagement.goToLoginView();
+ RouteManagement.goToBack();
+ RouteManagement.goToSendVerifyAccountOtpView();
} else {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("User Registration Error");
AppUtils.showSnackBar(
decodedData[StringValues.message],
StringValues.error,
@@ -146,19 +149,21 @@ class RegisterController extends GetxController {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("User Registration Error");
AppUtils.printLog(StringValues.internetConnError);
AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
} on TimeoutException {
AppUtils.closeDialog();
_isLoading.value = false;
update();
- AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.printLog("User Registration Error");
AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("User Registration Error");
AppUtils.printLog(StringValues.formatExcError);
AppUtils.printLog(e);
AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
@@ -166,6 +171,7 @@ class RegisterController extends GetxController {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("User Registration Error");
AppUtils.printLog(StringValues.errorOccurred);
AppUtils.printLog(exc);
AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
diff --git a/lib/modules/home/controllers/profile_controller.dart b/lib/modules/home/controllers/profile_controller.dart
index 99576da..947a380 100644
--- a/lib/modules/home/controllers/profile_controller.dart
+++ b/lib/modules/home/controllers/profile_controller.dart
@@ -59,12 +59,11 @@ class ProfileController extends GetxController {
setPostData = PostResponse.fromJson(decodedPostData);
_postList.clear();
_postList.addAll(_postData.value.results!);
+ AppUtils.printLog("Loading Profile Details From Local Storage Success");
+ return true;
} else {
AppUtils.printLog("Profile Post Data Not Found");
}
-
- AppUtils.printLog("Loading Profile Details From Local Storage Success");
- return true;
} else {
AppUtils.printLog("Loading Profile Details From Local Storage Error");
AppUtils.printLog(StringValues.profileDetailsNotFound);
diff --git a/lib/modules/home/views/tab_views/profile_tab.dart b/lib/modules/home/views/tab_views/profile_tab.dart
index 3d7f889..9a26f28 100644
--- a/lib/modules/home/views/tab_views/profile_tab.dart
+++ b/lib/modules/home/views/tab_views/profile_tab.dart
@@ -171,6 +171,33 @@ class ProfileTabView extends StatelessWidget {
style: AppStyles.style14Normal,
),
Dimens.boxHeight8,
+ if (logic.profileDetails.user!.website != null)
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Icon(
+ Icons.link,
+ size: Dimens.sixTeen,
+ color: Theme.of(Get.context!).textTheme.subtitle1!.color,
+ ),
+ Dimens.boxWidth8,
+ InkWell(
+ onTap: () => AppUtils.openUrl(
+ Uri.parse(logic.profileDetails.user!.website!)),
+ child: Text(
+ logic.profileDetails.user!.website!.contains('https://') ||
+ logic.profileDetails.user!.website!
+ .contains('http://')
+ ? Uri.parse(logic.profileDetails.user!.website!).host
+ : logic.profileDetails.user!.website!,
+ style: AppStyles.style13Bold.copyWith(
+ color: ColorValues.primaryColor,
+ ),
+ ),
+ ),
+ ],
+ ),
+ Dimens.boxHeight8,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
diff --git a/lib/modules/home/views/widgets/post_widget.dart b/lib/modules/home/views/widgets/post_widget.dart
index c4d9939..0315c3a 100644
--- a/lib/modules/home/views/widgets/post_widget.dart
+++ b/lib/modules/home/views/widgets/post_widget.dart
@@ -16,6 +16,7 @@ import 'package:social_media_app/global_widgets/expandable_text_widget.dart';
import 'package:social_media_app/global_widgets/primary_icon_btn.dart';
import 'package:social_media_app/global_widgets/primary_text_btn.dart';
import 'package:social_media_app/global_widgets/video_player_widget.dart';
+import 'package:social_media_app/helpers/get_time_ago_msg.dart';
import 'package:social_media_app/helpers/utils.dart';
import 'package:social_media_app/modules/home/controllers/post_controller.dart';
import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
@@ -90,25 +91,11 @@ class _PostWidgetState extends State {
),
],
),
- Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- Text(
- GetTimeAgo.parse(widget.post.createdAt),
- style: AppStyles.style12Normal.copyWith(
- color:
- Theme.of(Get.context!).textTheme.subtitle1!.color,
- ),
- ),
- Dimens.boxWidth8,
- NxIconButton(
- icon: CupertinoIcons.ellipsis_vertical,
- iconSize: Dimens.twenty,
- iconColor: Theme.of(context).textTheme.bodyText1!.color,
- onTap: _showHeaderOptionBottomSheet,
- ),
- ],
+ NxIconButton(
+ icon: CupertinoIcons.ellipsis_vertical,
+ iconSize: Dimens.twenty,
+ iconColor: Theme.of(context).textTheme.bodyText1!.color,
+ onTap: _showHeaderOptionBottomSheet,
),
],
),
@@ -248,73 +235,80 @@ class _PostWidgetState extends State {
padding: Dimens.edgeInsets0_4,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- GestureDetector(
- onTap: () => RouteManagement.goToPostPostLikedUsersView(
- widget.post.id!),
- child: Padding(
- padding: Dimens.edgeInsets4,
- child: RichText(
- text: TextSpan(
- children: [
- TextSpan(
- text: '${widget.post.likesCount}'
- .toCountingFormat(),
- style: AppStyles.style14Bold.copyWith(
- color: Theme.of(Get.context!)
- .textTheme
- .bodyText1!
- .color,
- ),
- ),
- TextSpan(
- text: ' Likes',
- style: AppStyles.style14Bold.copyWith(
- color: Theme.of(Get.context!)
- .textTheme
- .subtitle1!
- .color,
- ),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ GestureDetector(
+ onTap: () => RouteManagement.goToPostPostLikedUsersView(
+ widget.post.id!),
+ child: Padding(
+ padding: Dimens.edgeInsets4,
+ child: RichText(
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: '${widget.post.likesCount}'
+ .toCountingFormat(),
+ style: AppStyles.style14Bold.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ ),
+ TextSpan(
+ text: ' Likes',
+ style: AppStyles.style14Bold.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .subtitle1!
+ .color,
+ ),
+ ),
+ ],
),
- ],
+ ),
),
),
- ),
- ),
- Dimens.boxWidth16,
- GestureDetector(
- onTap: () =>
- RouteManagement.goToPostCommentsView(widget.post.id!),
- child: Padding(
- padding: Dimens.edgeInsets4,
- child: RichText(
- text: TextSpan(
- children: [
- TextSpan(
- text: '${widget.post.commentsCount}'
- .toCountingFormat(),
- style: AppStyles.style14Bold.copyWith(
- color: Theme.of(Get.context!)
- .textTheme
- .bodyText1!
- .color,
- ),
- ),
- TextSpan(
- text: ' Comments',
- style: AppStyles.style14Bold.copyWith(
- color: Theme.of(Get.context!)
- .textTheme
- .subtitle1!
- .color,
- ),
+ Dimens.boxWidth16,
+ GestureDetector(
+ onTap: () => RouteManagement.goToPostCommentsView(
+ widget.post.id!),
+ child: Padding(
+ padding: Dimens.edgeInsets4,
+ child: RichText(
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: '${widget.post.commentsCount}'
+ .toCountingFormat(),
+ style: AppStyles.style14Bold.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ ),
+ TextSpan(
+ text: ' Comments',
+ style: AppStyles.style14Bold.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .subtitle1!
+ .color,
+ ),
+ ),
+ ],
),
- ],
+ ),
),
),
- ),
+ ],
),
+ _buildPostTime(),
],
),
),
@@ -368,6 +362,19 @@ class _PostWidgetState extends State {
),
);
+ Widget _buildPostTime() {
+ GetTimeAgo.setCustomLocaleMessages('en', CustomMessages());
+ return Text(
+ GetTimeAgo.parse(
+ widget.post.createdAt,
+ pattern: 'dd MMM yyyy hh:mm a',
+ ),
+ style: AppStyles.style12Normal.copyWith(
+ color: Theme.of(Get.context!).textTheme.subtitle1!.color,
+ ),
+ );
+ }
+
_showHeaderOptionBottomSheet() => AppUtils.showBottomSheet(
[
// ListTile(
diff --git a/lib/modules/profile/bindings/edit_website_binding.dart b/lib/modules/profile/bindings/edit_website_binding.dart
new file mode 100644
index 0000000..b486301
--- /dev/null
+++ b/lib/modules/profile/bindings/edit_website_binding.dart
@@ -0,0 +1,9 @@
+import 'package:get/get.dart';
+import 'package:social_media_app/modules/profile/controllers/edit_website_controller.dart';
+
+class EditWebsiteBinding extends Bindings {
+ @override
+ void dependencies() {
+ Get.lazyPut(EditWebsiteController.new);
+ }
+}
diff --git a/lib/modules/profile/controllers/edit_website_controller.dart b/lib/modules/profile/controllers/edit_website_controller.dart
new file mode 100644
index 0000000..f0ce899
--- /dev/null
+++ b/lib/modules/profile/controllers/edit_website_controller.dart
@@ -0,0 +1,148 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:http/http.dart' as http;
+import 'package:social_media_app/apis/providers/api_provider.dart';
+import 'package:social_media_app/apis/services/auth_service.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/helpers/utils.dart';
+import 'package:social_media_app/helpers/validators.dart';
+import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
+import 'package:social_media_app/routes/route_management.dart';
+
+class EditWebsiteController extends GetxController {
+ static EditWebsiteController get find => Get.find();
+
+ final _profile = ProfileController.find;
+ final _auth = AuthService.find;
+
+ final _apiProvider = ApiProvider(http.Client());
+
+ final FocusScopeNode focusNode = FocusScopeNode();
+
+ final _isLoading = false.obs;
+ final _website = ''.obs;
+
+ /// Getters
+ bool get isLoading => _isLoading.value;
+
+ String get website => _website.value;
+
+ /// Setters
+ set setWebsite(String value) => _website.value = value;
+
+ void onChangeWebsite(String url) {
+ setWebsite = url;
+ update();
+ }
+
+ @override
+ void onInit() {
+ initializeFields();
+ super.onInit();
+ }
+
+ void initializeFields() async {
+ if (_profile.profileDetails.user != null) {
+ var user = _profile.profileDetails.user!;
+ setWebsite = user.website ?? '';
+ }
+ }
+
+ Future _updateWebsite(String website) async {
+ if (website.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterWebsiteUrl,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ final body = {'website': website};
+
+ AppUtils.printLog("Update Website Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response = await _apiProvider.updateProfile(_auth.token, body);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ await _profile.fetchProfileDetails(fetchPost: false);
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Success");
+ RouteManagement.goToBack();
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.success,
+ );
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Update Website Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ Future updateWebsite() async {
+ AppUtils.closeFocus();
+ if (_website.value.isEmpty) {
+ return;
+ }
+ if (_website.value == _profile.profileDetails.user!.website?.trim()) {
+ return;
+ }
+ if (!Validators.isValidUrl(_website.value)) {
+ AppUtils.showSnackBar(
+ StringValues.enterValidUrl,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ await _updateWebsite(_website.value.trim());
+ }
+}
diff --git a/lib/modules/profile/views/edit_views/edit_gender_view.dart b/lib/modules/profile/views/edit_views/edit_gender_view.dart
index d7696d5..ca3c68b 100644
--- a/lib/modules/profile/views/edit_views/edit_gender_view.dart
+++ b/lib/modules/profile/views/edit_views/edit_gender_view.dart
@@ -46,8 +46,15 @@ class EditGenderView extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
+ /// Male
+
NxRadioTile(
- padding: Dimens.edgeInsets16_0,
+ padding: Dimens.edgeInsets8,
+ bgColor: Theme.of(Get.context!).dialogBackgroundColor,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(Dimens.eight),
+ topRight: Radius.circular(Dimens.eight),
+ ),
onTap: () => logic.setGender = StringValues.male,
onChanged: (value) {
logic.setGender = value.toString();
@@ -56,8 +63,14 @@ class EditGenderView extends StatelessWidget {
value: StringValues.male,
groupValue: logic.gender,
),
+
+ Dimens.divider,
+
+ /// Female
+
NxRadioTile(
- padding: Dimens.edgeInsets16_0,
+ padding: Dimens.edgeInsets8,
+ bgColor: Theme.of(Get.context!).dialogBackgroundColor,
onTap: () => logic.setGender = StringValues.female,
onChanged: (value) {
logic.setGender = value.toString();
@@ -66,8 +79,18 @@ class EditGenderView extends StatelessWidget {
value: StringValues.female,
groupValue: logic.gender,
),
+
+ Dimens.divider,
+
+ /// Others
+
NxRadioTile(
- padding: Dimens.edgeInsets16_0,
+ padding: Dimens.edgeInsets8,
+ bgColor: Theme.of(Get.context!).dialogBackgroundColor,
+ borderRadius: BorderRadius.only(
+ bottomLeft: Radius.circular(Dimens.eight),
+ bottomRight: Radius.circular(Dimens.eight),
+ ),
onTap: () => logic.setGender = StringValues.others,
onChanged: (value) {
logic.setGender = value.toString();
diff --git a/lib/modules/profile/views/edit_views/edit_website_view.dart b/lib/modules/profile/views/edit_views/edit_website_view.dart
new file mode 100644
index 0000000..8d00eb4
--- /dev/null
+++ b/lib/modules/profile/views/edit_views/edit_website_view.dart
@@ -0,0 +1,89 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:social_media_app/constants/colors.dart';
+import 'package:social_media_app/constants/dimens.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/constants/styles.dart';
+import 'package:social_media_app/global_widgets/custom_app_bar.dart';
+import 'package:social_media_app/global_widgets/primary_filled_btn.dart';
+import 'package:social_media_app/modules/profile/controllers/edit_website_controller.dart';
+
+class EditWebsiteView extends StatelessWidget {
+ const EditWebsiteView({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
+ child: Scaffold(
+ body: SafeArea(
+ child: SizedBox(
+ width: Dimens.screenWidth,
+ height: Dimens.screenHeight,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ NxAppBar(
+ title: StringValues.website,
+ padding: Dimens.edgeInsets8_16,
+ ),
+ Dimens.boxHeight24,
+ _buildBody(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildBody() => GetBuilder(
+ builder: (logic) => Expanded(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: Dimens.edgeInsets0_16,
+ child: FocusScope(
+ node: logic.focusNode,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Container(
+ height: Dimens.fiftySix,
+ constraints: BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ decoration: InputDecoration(
+ hintText: StringValues.website,
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ ),
+ maxLines: 1,
+ initialValue: logic.website,
+ keyboardType: TextInputType.url,
+ style: AppStyles.style14Normal.copyWith(
+ color:
+ Theme.of(Get.context!).textTheme.bodyText1!.color,
+ ),
+ onChanged: (value) => logic.onChangeWebsite(value),
+ onEditingComplete: logic.focusNode.unfocus,
+ ),
+ ),
+ Dimens.boxHeight40,
+ NxFilledButton(
+ onTap: logic.updateWebsite,
+ label: StringValues.save.toUpperCase(),
+ ),
+ Dimens.boxHeight16,
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+}
diff --git a/lib/modules/profile/views/profile_details_view.dart b/lib/modules/profile/views/profile_details_view.dart
index 0a3ce8a..c5d2825 100644
--- a/lib/modules/profile/views/profile_details_view.dart
+++ b/lib/modules/profile/views/profile_details_view.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
+import 'package:social_media_app/constants/colors.dart';
import 'package:social_media_app/constants/data.dart';
import 'package:social_media_app/constants/dimens.dart';
import 'package:social_media_app/constants/strings.dart';
@@ -231,10 +232,6 @@ class ProfileDetailsView extends StatelessWidget {
NxListTile(
padding: Dimens.edgeInsets12_8,
bgColor: Theme.of(Get.context!).dialogBackgroundColor,
- borderRadius: BorderRadius.only(
- bottomLeft: Radius.circular(Dimens.eight),
- bottomRight: Radius.circular(Dimens.eight),
- ),
leading: const Icon(Icons.male_outlined),
title: Text(
StringValues.gender,
@@ -260,6 +257,39 @@ class ProfileDetailsView extends StatelessWidget {
),
onTap: RouteManagement.goToEditGenderView,
),
+
+ Dimens.divider,
+
+ /// Website
+
+ NxListTile(
+ padding: Dimens.edgeInsets12_8,
+ bgColor: Theme.of(Get.context!).dialogBackgroundColor,
+ borderRadius: BorderRadius.only(
+ bottomLeft: Radius.circular(Dimens.eight),
+ bottomRight: Radius.circular(Dimens.eight),
+ ),
+ leading: const Icon(Icons.link),
+ title: Text(
+ StringValues.website,
+ style: AppStyles.style12Normal.copyWith(
+ color:
+ Theme.of(Get.context!).textTheme.subtitle1!.color,
+ ),
+ ),
+ subtitle: Text(
+ logic.profileDetails.user!.website ?? 'Add website',
+ style: AppStyles.style16Normal.copyWith(
+ color: logic.profileDetails.user!.website == null
+ ? Theme.of(Get.context!)
+ .textTheme
+ .subtitle1
+ ?.color
+ : ColorValues.primaryColor,
+ ),
+ ),
+ onTap: RouteManagement.goToEditWebsiteView,
+ ),
Dimens.boxHeight16,
],
),
diff --git a/lib/modules/settings/bindings/change_email_binding.dart b/lib/modules/settings/bindings/change_email_binding.dart
new file mode 100644
index 0000000..3610ce8
--- /dev/null
+++ b/lib/modules/settings/bindings/change_email_binding.dart
@@ -0,0 +1,9 @@
+import 'package:get/get.dart';
+import 'package:social_media_app/modules/settings/controllers/change_email_controller.dart';
+
+class ChangeEmailBinding extends Bindings {
+ @override
+ void dependencies() {
+ Get.lazyPut(ChangeEmailController.new);
+ }
+}
diff --git a/lib/modules/settings/bindings/change_phone_binding.dart b/lib/modules/settings/bindings/change_phone_binding.dart
new file mode 100644
index 0000000..1e42840
--- /dev/null
+++ b/lib/modules/settings/bindings/change_phone_binding.dart
@@ -0,0 +1,9 @@
+import 'package:get/get.dart';
+import 'package:social_media_app/modules/settings/controllers/change_phone_controller.dart';
+
+class ChangePhoneBinding extends Bindings {
+ @override
+ void dependencies() {
+ Get.lazyPut(ChangePhoneController.new);
+ }
+}
diff --git a/lib/modules/settings/controllers/change_email_controller.dart b/lib/modules/settings/controllers/change_email_controller.dart
new file mode 100644
index 0000000..fb453f6
--- /dev/null
+++ b/lib/modules/settings/controllers/change_email_controller.dart
@@ -0,0 +1,214 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:http/http.dart' as http;
+import 'package:social_media_app/apis/providers/api_provider.dart';
+import 'package:social_media_app/apis/services/auth_service.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/helpers/utils.dart';
+import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
+import 'package:social_media_app/routes/route_management.dart';
+
+class ChangeEmailController extends GetxController {
+ static ChangeEmailController get find => Get.find();
+
+ final _auth = AuthService.find;
+ final profile = ProfileController.find;
+
+ final _apiProvider = ApiProvider(http.Client());
+
+ final _isLoading = false.obs;
+ final _otpSent = false.obs;
+ final emailTextController = TextEditingController();
+ final otpTextController = TextEditingController();
+
+ final FocusScopeNode focusNode = FocusScopeNode();
+
+ /// Getters
+ bool get isLoading => _isLoading.value;
+
+ bool get otpSent => _otpSent.value;
+
+ Future _sendChangeEmailOtp(String email) async {
+ if (email.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterEmail,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ if (profile.profileDetails.user!.email == email) {
+ AppUtils.showSnackBar(
+ StringValues.enterDifferentEmail,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ final body = {'email': email};
+
+ AppUtils.printLog("Send Change Email OTP Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response = await _apiProvider.sendChangeEmailOtp(_auth.token, body);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ AppUtils.printLog("Send Change Email OTP Success");
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ _otpSent.value = true;
+ update();
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.success,
+ );
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Email OTP Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Email OTP Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Email OTP Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Email OTP Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Email OTP Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ Future _changeEmail(String otp, String email) async {
+ if (otp.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterOtp,
+ StringValues.warning,
+ );
+ return;
+ }
+ if (email.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterEmail,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ final body = {
+ 'otp': otp,
+ 'email': email,
+ };
+
+ AppUtils.printLog("Change Email Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response = await _apiProvider.changeEmail(_auth.token, body);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ AppUtils.printLog("Change Email Success");
+ await profile.fetchProfileDetails(fetchPost: false);
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ RouteManagement.goToBack();
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.success,
+ );
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Email Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Email Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Email Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Email Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Email Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ Future changeEmail() async {
+ AppUtils.closeFocus();
+ await _changeEmail(
+ otpTextController.text.trim(),
+ emailTextController.text.trim(),
+ );
+ }
+
+ Future sendChangeEmailOtp() async {
+ AppUtils.closeFocus();
+ await _sendChangeEmailOtp(emailTextController.text.trim());
+ }
+}
diff --git a/lib/modules/settings/controllers/change_password_controller.dart b/lib/modules/settings/controllers/change_password_controller.dart
index 1e0177b..561cc65 100644
--- a/lib/modules/settings/controllers/change_password_controller.dart
+++ b/lib/modules/settings/controllers/change_password_controller.dart
@@ -9,6 +9,7 @@ import 'package:social_media_app/apis/providers/api_provider.dart';
import 'package:social_media_app/apis/services/auth_service.dart';
import 'package:social_media_app/constants/strings.dart';
import 'package:social_media_app/helpers/utils.dart';
+import 'package:social_media_app/routes/route_management.dart';
class ChangePasswordController extends GetxController {
static ChangePasswordController get find => Get.find();
@@ -76,7 +77,7 @@ class ChangePasswordController extends GetxController {
'confirmPassword': confPassword,
};
- AppUtils.printLog("Change Password Request...");
+ AppUtils.printLog("Change Password Request");
AppUtils.showLoadingDialog();
_isLoading.value = true;
update();
@@ -87,14 +88,16 @@ class ChangePasswordController extends GetxController {
final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
if (response.statusCode == 200) {
- await _auth.logout();
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("Change Password Success");
+ RouteManagement.goToBack();
} else {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("Change Password Error");
AppUtils.showSnackBar(
decodedData[StringValues.message],
StringValues.error,
@@ -104,19 +107,21 @@ class ChangePasswordController extends GetxController {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("Change Password Error");
AppUtils.printLog(StringValues.internetConnError);
AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
} on TimeoutException {
AppUtils.closeDialog();
_isLoading.value = false;
update();
- AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.printLog("Change Password Error");
AppUtils.printLog(StringValues.connTimedOut);
AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
} on FormatException catch (e) {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("Change Password Error");
AppUtils.printLog(StringValues.formatExcError);
AppUtils.printLog(e);
AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
@@ -124,6 +129,7 @@ class ChangePasswordController extends GetxController {
AppUtils.closeDialog();
_isLoading.value = false;
update();
+ AppUtils.printLog("Change Password Error");
AppUtils.printLog(StringValues.errorOccurred);
AppUtils.printLog(exc);
AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
diff --git a/lib/modules/settings/controllers/change_phone_controller.dart b/lib/modules/settings/controllers/change_phone_controller.dart
new file mode 100644
index 0000000..bcdf955
--- /dev/null
+++ b/lib/modules/settings/controllers/change_phone_controller.dart
@@ -0,0 +1,261 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:fl_country_code_picker/fl_country_code_picker.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:http/http.dart' as http;
+import 'package:social_media_app/apis/providers/api_provider.dart';
+import 'package:social_media_app/apis/services/auth_service.dart';
+import 'package:social_media_app/constants/dimens.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/helpers/utils.dart';
+import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
+import 'package:social_media_app/routes/route_management.dart';
+
+class ChangePhoneController extends GetxController {
+ static ChangePhoneController get find => Get.find();
+
+ final _auth = AuthService.find;
+ final profile = ProfileController.find;
+
+ final _apiProvider = ApiProvider(http.Client());
+
+ final _isLoading = false.obs;
+ final _otpSent = false.obs;
+ final _phone = ''.obs;
+ final _otp = ''.obs;
+ final FocusScopeNode focusNode = FocusScopeNode();
+ CountryCode code = const CountryCode(
+ name: 'India',
+ code: 'IN',
+ dialCode: '+91',
+ );
+
+ /// Getters
+ bool get isLoading => _isLoading.value;
+
+ bool get otpSent => _otpSent.value;
+
+ String get phone => _phone.value;
+
+ String get otp => _otp.value;
+
+ /// Setters
+ set phone(String val) => _phone.value = val;
+
+ set otp(String val) => _otp.value = val;
+
+ void onChangeCountryCode(CountryCode code) {
+ code = code;
+ update();
+ }
+
+ void onChangePhone(String value) {
+ phone = value;
+ update();
+ }
+
+ void onChangeOtp(String value) {
+ otp = value;
+ update();
+ }
+
+ Future _sendAddChangePhoneOtp() async {
+ if (_phone.value.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterPhoneNo,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ if (profile.profileDetails.user!.phone == phone) {
+ AppUtils.showSnackBar(
+ StringValues.enterDifferentPhoneNo,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ final body = {
+ "phone": _phone.value,
+ "countryCode": code.dialCode,
+ };
+
+ AppUtils.printLog("Send Change Phone OTP Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response =
+ await _apiProvider.sendAddChangePhoneOtp(_auth.token, body);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ AppUtils.printLog("Send Change Phone OTP Success");
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ _otpSent.value = true;
+ update();
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.success,
+ );
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Phone OTP Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Phone OTP Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Phone OTP Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Phone OTP Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Send Change Phone OTP Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ Future _addChangePhone() async {
+ if (_otp.value.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterOtp,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ if (_phone.value.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterPhoneNo,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ final body = {
+ 'otp': _otp.value,
+ "phone": _phone.value,
+ "countryCode": code.dialCode,
+ };
+
+ AppUtils.printLog("Change Phone Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response = await _apiProvider.addChangePhone(_auth.token, body);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ AppUtils.printLog("Change Phone Success");
+ await profile.fetchProfileDetails(fetchPost: false);
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ RouteManagement.goToBack();
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.success,
+ );
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Phone Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Phone Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Phone Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Phone Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Change Phone Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ void showCountryCodePicker() async {
+ const countryPicker = FlCountryCodePicker();
+ final code = await countryPicker.showPicker(
+ context: Get.context!,
+ fullScreen: false,
+ pickerMinHeight: Dimens.screenHeight * 0.5,
+ pickerMaxHeight: Dimens.screenHeight * 0.75,
+ initialSelectedLocale: 'IN',
+ );
+ if (code != null) {
+ onChangeCountryCode(code);
+ }
+ }
+
+ Future addChangePhone() async {
+ AppUtils.closeFocus();
+ await _addChangePhone();
+ }
+
+ Future sendAddChangePhoneOtp() async {
+ AppUtils.closeFocus();
+ await _sendAddChangePhoneOtp();
+ }
+}
diff --git a/lib/modules/settings/views/pages/about_settings_view.dart b/lib/modules/settings/views/pages/about_settings_view.dart
index 837cfc5..6fa6376 100644
--- a/lib/modules/settings/views/pages/about_settings_view.dart
+++ b/lib/modules/settings/views/pages/about_settings_view.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:social_media_app/constants/assets.dart';
+import 'package:social_media_app/constants/colors.dart';
import 'package:social_media_app/constants/dimens.dart';
import 'package:social_media_app/constants/strings.dart';
import 'package:social_media_app/constants/styles.dart';
@@ -107,16 +108,41 @@ class AboutSettingsView extends StatelessWidget {
],
),
const Spacer(),
- Center(
- child: ClipRRect(
- borderRadius: BorderRadius.circular(Dimens.hundred),
- child: NxAssetImage(
- imgAsset: AssetValues.makeInIndia,
- fit: BoxFit.cover,
- width: Dimens.hundred,
- height: Dimens.hundred,
+ Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ 'Made with ❤️ by',
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!).textTheme.subtitle1!.color,
+ ),
),
- ),
+ Dimens.boxHeight4,
+ InkWell(
+ onTap: () =>
+ AppUtils.openUrl(Uri.parse(StringValues.portfolioUrl)),
+ child: Text(
+ 'Nikhil Rajput',
+ style: AppStyles.style16Bold.copyWith(
+ color: ColorValues.primaryColor,
+ ),
+ ),
+ ),
+ Dimens.boxHeight16,
+ Center(
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(Dimens.hundred),
+ child: NxAssetImage(
+ imgAsset: AssetValues.makeInIndia,
+ fit: BoxFit.cover,
+ width: Dimens.sixtyFour,
+ height: Dimens.sixtyFour,
+ ),
+ ),
+ ),
+ ],
),
Dimens.boxHeight16,
],
diff --git a/lib/modules/settings/views/pages/account/change_email_view.dart b/lib/modules/settings/views/pages/account/change_email_view.dart
new file mode 100644
index 0000000..a664d1b
--- /dev/null
+++ b/lib/modules/settings/views/pages/account/change_email_view.dart
@@ -0,0 +1,154 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:get/get.dart';
+import 'package:social_media_app/constants/colors.dart';
+import 'package:social_media_app/constants/dimens.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/constants/styles.dart';
+import 'package:social_media_app/global_widgets/custom_app_bar.dart';
+import 'package:social_media_app/global_widgets/primary_filled_btn.dart';
+import 'package:social_media_app/modules/settings/controllers/change_email_controller.dart';
+
+class ChangeEmailView extends StatelessWidget {
+ const ChangeEmailView({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
+ child: Scaffold(
+ body: SafeArea(
+ child: SizedBox(
+ width: Dimens.screenWidth,
+ height: Dimens.screenHeight,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ NxAppBar(
+ title: StringValues.changeEmail,
+ padding: Dimens.edgeInsets8_16,
+ ),
+ Dimens.boxHeight24,
+ _buildBody(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildBody() => GetBuilder(
+ builder: (logic) {
+ return Expanded(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: Dimens.edgeInsets0_16,
+ child: FocusScope(
+ node: logic.focusNode,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ RichText(
+ text: TextSpan(
+ children: [
+ const TextSpan(
+ text: 'Your current email is ',
+ ),
+ TextSpan(
+ text: logic.profile.profileDetails.user!.email,
+ style: AppStyles.style14Bold,
+ ),
+ const TextSpan(
+ text:
+ '. Enter the email you want to change with it.'),
+ ],
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ ),
+ ),
+ Dimens.boxHeight32,
+ Container(
+ height: Dimens.fiftySix,
+ constraints:
+ BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ decoration: InputDecoration(
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ hintText: StringValues.email,
+ ),
+ enabled: logic.otpSent ? false : true,
+ keyboardType: TextInputType.emailAddress,
+ maxLines: 1,
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ controller: logic.emailTextController,
+ ),
+ ),
+ if (logic.otpSent) Dimens.boxHeight16,
+ if (logic.otpSent)
+ Container(
+ height: Dimens.fiftySix,
+ constraints:
+ BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ decoration: InputDecoration(
+ border: OutlineInputBorder(
+ borderRadius:
+ BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ hintText: StringValues.otp,
+ ),
+ keyboardType: TextInputType.number,
+ maxLines: 1,
+ inputFormatters: [
+ FilteringTextInputFormatter.digitsOnly,
+ LengthLimitingTextInputFormatter(6),
+ ],
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ controller: logic.otpTextController,
+ onEditingComplete: logic.focusNode.nextFocus,
+ ),
+ ),
+ Dimens.boxHeight40,
+ NxFilledButton(
+ onTap: logic.otpSent
+ ? logic.changeEmail
+ : logic.sendChangeEmailOtp,
+ label: logic.otpSent
+ ? StringValues.save.toUpperCase()
+ : StringValues.next.toUpperCase(),
+ ),
+ Dimens.boxHeight16,
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ );
+}
diff --git a/lib/modules/settings/views/pages/account/change_phone_view.dart b/lib/modules/settings/views/pages/account/change_phone_view.dart
new file mode 100644
index 0000000..610d58f
--- /dev/null
+++ b/lib/modules/settings/views/pages/account/change_phone_view.dart
@@ -0,0 +1,217 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:get/get.dart';
+import 'package:social_media_app/constants/colors.dart';
+import 'package:social_media_app/constants/dimens.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/constants/styles.dart';
+import 'package:social_media_app/global_widgets/custom_app_bar.dart';
+import 'package:social_media_app/global_widgets/primary_filled_btn.dart';
+import 'package:social_media_app/modules/settings/controllers/change_phone_controller.dart';
+
+class ChangePhoneView extends StatelessWidget {
+ const ChangePhoneView({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
+ child: Scaffold(
+ body: SafeArea(
+ child: SizedBox(
+ width: Dimens.screenWidth,
+ height: Dimens.screenHeight,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ NxAppBar(
+ title: StringValues.changePhone,
+ padding: Dimens.edgeInsets8_16,
+ ),
+ Dimens.boxHeight24,
+ _buildBody(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildBody() => GetBuilder(
+ builder: (logic) {
+ return Expanded(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: Dimens.edgeInsets0_16,
+ child: FocusScope(
+ node: logic.focusNode,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ if (logic.profile.profileDetails.user!.phone != null)
+ RichText(
+ text: TextSpan(
+ children: [
+ const TextSpan(
+ text: 'Your current phone number is ',
+ ),
+ TextSpan(
+ text: logic.profile.profileDetails.user!.phone,
+ style: AppStyles.style14Bold,
+ ),
+ const TextSpan(
+ text:
+ '. Enter the new phone number you want to change with it.'),
+ ],
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ ),
+ )
+ else
+ RichText(
+ text: TextSpan(
+ children: const [
+ TextSpan(
+ text:
+ 'Enter a phone number you want to add.'),
+ ],
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ ),
+ ),
+ Dimens.boxHeight32,
+ Row(
+ children: [
+ InkWell(
+ onTap: logic.showCountryCodePicker,
+ child: Container(
+ height: Dimens.fiftySix,
+ padding: Dimens.edgeInsets0_8,
+ decoration: BoxDecoration(
+ border: Border.all(
+ color: Theme.of(Get.context!).dividerColor,
+ ),
+ borderRadius:
+ BorderRadius.circular(Dimens.eight),
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(
+ width: Dimens.twentyFour,
+ height: Dimens.twentyFour,
+ child: logic.code.flagImage,
+ ),
+ Dimens.boxWidth8,
+ Text(
+ logic.code.dialCode,
+ style: AppStyles.style16Bold,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Dimens.boxWidth16,
+ Expanded(
+ child: Container(
+ height: Dimens.fiftySix,
+ constraints:
+ BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ decoration: InputDecoration(
+ border: OutlineInputBorder(
+ borderRadius:
+ BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ hintText: StringValues.phoneNo,
+ ),
+ inputFormatters: [
+ FilteringTextInputFormatter.digitsOnly,
+ LengthLimitingTextInputFormatter(12),
+ ],
+ enabled: logic.otpSent ? false : true,
+ keyboardType: TextInputType.phone,
+ maxLines: 1,
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ onChanged: (value) =>
+ logic.onChangePhone(value),
+ onEditingComplete: () =>
+ logic.focusNode.unfocus(),
+ ),
+ ),
+ ),
+ ],
+ ),
+ Dimens.boxHeight16,
+ if (logic.otpSent) Dimens.boxHeight16,
+ if (logic.otpSent)
+ Container(
+ height: Dimens.fiftySix,
+ constraints:
+ BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ decoration: InputDecoration(
+ border: OutlineInputBorder(
+ borderRadius:
+ BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ hintText: StringValues.otp,
+ ),
+ keyboardType: TextInputType.number,
+ maxLines: 1,
+ inputFormatters: [
+ FilteringTextInputFormatter.digitsOnly,
+ LengthLimitingTextInputFormatter(6),
+ ],
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ onChanged: (value) => logic.onChangeOtp(value),
+ onEditingComplete: () => logic.focusNode.unfocus(),
+ ),
+ ),
+ Dimens.boxHeight40,
+ NxFilledButton(
+ onTap: logic.otpSent
+ ? logic.addChangePhone
+ : logic.sendAddChangePhoneOtp,
+ label: logic.otpSent
+ ? StringValues.save.toUpperCase()
+ : StringValues.next.toUpperCase(),
+ ),
+ Dimens.boxHeight16,
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ );
+}
diff --git a/lib/modules/settings/views/pages/account_settings_view.dart b/lib/modules/settings/views/pages/account_settings_view.dart
index 9929abf..e824ecd 100644
--- a/lib/modules/settings/views/pages/account_settings_view.dart
+++ b/lib/modules/settings/views/pages/account_settings_view.dart
@@ -6,6 +6,7 @@ import 'package:social_media_app/constants/styles.dart';
import 'package:social_media_app/extensions/string_extensions.dart';
import 'package:social_media_app/global_widgets/custom_app_bar.dart';
import 'package:social_media_app/global_widgets/custom_list_tile.dart';
+import 'package:social_media_app/routes/route_management.dart';
class AccountSettingsView extends StatelessWidget {
const AccountSettingsView({Key? key}) : super(key: key);
@@ -58,9 +59,12 @@ class AccountSettingsView extends StatelessWidget {
color: Theme.of(Get.context!).textTheme.bodyText1!.color,
),
title: Text(
- StringValues.changeEmail.toTitleCase(),
+ StringValues.changeEmailAddress.toTitleCase(),
style: AppStyles.style14Bold,
),
+ onTap: () => RouteManagement.goToVerifyPasswordView(
+ RouteManagement.goToChangeEmailSettingsView,
+ ),
),
Dimens.divider,
@@ -79,6 +83,9 @@ class AccountSettingsView extends StatelessWidget {
StringValues.changePhoneNo.toTitleCase(),
style: AppStyles.style14Bold,
),
+ onTap: () => RouteManagement.goToVerifyPasswordView(
+ RouteManagement.goToChangePhoneSettingsView,
+ ),
),
Dimens.divider,
diff --git a/lib/modules/settings/views/pages/theme_settings_view.dart b/lib/modules/settings/views/pages/theme_settings_view.dart
index 8493dcf..29998be 100644
--- a/lib/modules/settings/views/pages/theme_settings_view.dart
+++ b/lib/modules/settings/views/pages/theme_settings_view.dart
@@ -50,12 +50,12 @@ class ThemeSettingsView extends StatelessWidget {
topLeft: Radius.circular(Dimens.eight),
topRight: Radius.circular(Dimens.eight),
),
- onTap: () => logic.setThemeMode(appThemeModes.elementAt(0)),
+ onTap: () => logic.setThemeMode(AppThemeModes.system),
onChanged: (value) {
logic.setThemeMode(value);
},
- title: appThemeModes.elementAt(0).toString(),
- value: appThemeModes.elementAt(0).toString(),
+ title: StringValues.system.toString(),
+ value: AppThemeModes.system,
groupValue: logic.themeMode,
),
@@ -66,12 +66,12 @@ class ThemeSettingsView extends StatelessWidget {
NxRadioTile(
padding: Dimens.edgeInsets8,
bgColor: Theme.of(Get.context!).dialogBackgroundColor,
- onTap: () => logic.setThemeMode(appThemeModes.elementAt(1)),
+ onTap: () => logic.setThemeMode(AppThemeModes.light),
onChanged: (value) {
logic.setThemeMode(value);
},
- title: appThemeModes.elementAt(1).toString(),
- value: appThemeModes.elementAt(1).toString(),
+ title: StringValues.light.toString(),
+ value: AppThemeModes.light,
groupValue: logic.themeMode,
),
@@ -86,12 +86,12 @@ class ThemeSettingsView extends StatelessWidget {
bottomLeft: Radius.circular(Dimens.eight),
bottomRight: Radius.circular(Dimens.eight),
),
- onTap: () => logic.setThemeMode(appThemeModes.elementAt(2)),
+ onTap: () => logic.setThemeMode(AppThemeModes.dark),
onChanged: (value) {
logic.setThemeMode(value);
},
- title: appThemeModes.elementAt(2).toString(),
- value: appThemeModes.elementAt(2).toString(),
+ title: StringValues.dark.toString(),
+ value: AppThemeModes.dark,
groupValue: logic.themeMode,
),
],
diff --git a/lib/modules/user/user_profile_view.dart b/lib/modules/user/user_profile_view.dart
index b799e0f..2184fc4 100644
--- a/lib/modules/user/user_profile_view.dart
+++ b/lib/modules/user/user_profile_view.dart
@@ -16,7 +16,6 @@ import 'package:social_media_app/global_widgets/post_thumb_widget.dart';
import 'package:social_media_app/global_widgets/primary_outlined_btn.dart';
import 'package:social_media_app/global_widgets/primary_text_btn.dart';
import 'package:social_media_app/global_widgets/shimmer_loading.dart';
-import 'package:social_media_app/modules/home/controllers/profile_controller.dart';
import 'package:social_media_app/modules/user/user_details_controller.dart';
import 'package:social_media_app/routes/route_management.dart';
@@ -279,7 +278,6 @@ class UserProfileView extends StatelessWidget {
Container _buildCountDetails(UserDetailsController logic) {
final user = logic.userDetails.user;
- final profile = ProfileController.find;
return Container(
width: Dimens.screenWidth,
padding: Dimens.edgeInsets8_0,
diff --git a/lib/modules/verify_password/verify_password_bindings.dart b/lib/modules/verify_password/verify_password_bindings.dart
new file mode 100644
index 0000000..5234cc3
--- /dev/null
+++ b/lib/modules/verify_password/verify_password_bindings.dart
@@ -0,0 +1,9 @@
+import 'package:get/get.dart';
+import 'package:social_media_app/modules/verify_password/verify_password_controller.dart';
+
+class VerifyPasswordBinding implements Bindings {
+ @override
+ void dependencies() {
+ Get.lazyPut(VerifyPasswordController.new);
+ }
+}
diff --git a/lib/modules/verify_password/verify_password_controller.dart b/lib/modules/verify_password/verify_password_controller.dart
new file mode 100644
index 0000000..f67488a
--- /dev/null
+++ b/lib/modules/verify_password/verify_password_controller.dart
@@ -0,0 +1,113 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:flutter/widgets.dart';
+import 'package:get/get.dart';
+import 'package:http/http.dart' as http;
+import 'package:social_media_app/apis/providers/api_provider.dart';
+import 'package:social_media_app/apis/services/auth_service.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/helpers/utils.dart';
+import 'package:social_media_app/routes/route_management.dart';
+
+class VerifyPasswordController extends GetxController {
+ static VerifyPasswordController get find => Get.find();
+
+ final _auth = AuthService.find;
+
+ final _apiProvider = ApiProvider(http.Client());
+
+ final passwordTextController = TextEditingController();
+
+ final FocusScopeNode focusNode = FocusScopeNode();
+
+ final _isLoading = false.obs;
+ final _showPassword = true.obs;
+
+ /// Getters
+ bool get isLoading => _isLoading.value;
+
+ bool get showPassword => _showPassword.value;
+
+ void toggleViewPassword() {
+ _showPassword(!_showPassword.value);
+ update();
+ }
+
+ Future _verifyPassword(String password) async {
+ if (password.isEmpty) {
+ AppUtils.showSnackBar(
+ StringValues.enterPassword,
+ StringValues.warning,
+ );
+ return;
+ }
+
+ var cb = Get.arguments;
+
+ AppUtils.printLog("Verify Password Request");
+ AppUtils.showLoadingDialog();
+ _isLoading.value = true;
+ update();
+
+ try {
+ final response = await _apiProvider.verifyPassword(_auth.token, password);
+
+ final decodedData = jsonDecode(utf8.decode(response.bodyBytes));
+
+ if (response.statusCode == 200) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Success");
+ RouteManagement.goToBack();
+ cb();
+ } else {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Error");
+ AppUtils.showSnackBar(
+ decodedData[StringValues.message],
+ StringValues.error,
+ );
+ }
+ } on SocketException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Error");
+ AppUtils.printLog(StringValues.internetConnError);
+ AppUtils.showSnackBar(StringValues.internetConnError, StringValues.error);
+ } on TimeoutException {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Error");
+ AppUtils.printLog(StringValues.connTimedOut);
+ AppUtils.showSnackBar(StringValues.connTimedOut, StringValues.error);
+ } on FormatException catch (e) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Error");
+ AppUtils.printLog(StringValues.formatExcError);
+ AppUtils.printLog(e);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ } catch (exc) {
+ AppUtils.closeDialog();
+ _isLoading.value = false;
+ update();
+ AppUtils.printLog("Verify Password Error");
+ AppUtils.printLog(StringValues.errorOccurred);
+ AppUtils.printLog(exc);
+ AppUtils.showSnackBar(StringValues.errorOccurred, StringValues.error);
+ }
+ }
+
+ Future verifyPassword() async {
+ AppUtils.closeFocus();
+ await _verifyPassword(passwordTextController.text.trim());
+ }
+}
diff --git a/lib/modules/verify_password/verify_password_view.dart b/lib/modules/verify_password/verify_password_view.dart
new file mode 100644
index 0000000..0ddac60
--- /dev/null
+++ b/lib/modules/verify_password/verify_password_view.dart
@@ -0,0 +1,103 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:social_media_app/constants/colors.dart';
+import 'package:social_media_app/constants/dimens.dart';
+import 'package:social_media_app/constants/strings.dart';
+import 'package:social_media_app/constants/styles.dart';
+import 'package:social_media_app/global_widgets/custom_app_bar.dart';
+import 'package:social_media_app/global_widgets/primary_filled_btn.dart';
+import 'package:social_media_app/modules/verify_password/verify_password_controller.dart';
+
+class VerifyPasswordView extends StatelessWidget {
+ const VerifyPasswordView({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
+ child: Scaffold(
+ body: SafeArea(
+ child: SizedBox(
+ width: Dimens.screenWidth,
+ height: Dimens.screenHeight,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ NxAppBar(
+ title: StringValues.verifyPassword,
+ padding: Dimens.edgeInsets8_16,
+ ),
+ Dimens.boxHeight24,
+ _buildBody(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildBody() => GetBuilder(
+ builder: (logic) {
+ return Expanded(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: Dimens.edgeInsets0_16,
+ child: FocusScope(
+ node: logic.focusNode,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Container(
+ height: Dimens.fiftySix,
+ constraints:
+ BoxConstraints(maxWidth: Dimens.screenWidth),
+ child: TextFormField(
+ obscureText: logic.showPassword,
+ decoration: InputDecoration(
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(Dimens.eight),
+ ),
+ hintStyle: AppStyles.style14Normal.copyWith(
+ color: ColorValues.grayColor,
+ ),
+ hintText: StringValues.currentPassword,
+ suffixIcon: InkWell(
+ onTap: logic.toggleViewPassword,
+ child: Icon(
+ logic.showPassword
+ ? CupertinoIcons.eye
+ : CupertinoIcons.eye_slash,
+ ),
+ ),
+ ),
+ keyboardType: TextInputType.visiblePassword,
+ maxLines: 1,
+ style: AppStyles.style14Normal.copyWith(
+ color: Theme.of(Get.context!)
+ .textTheme
+ .bodyText1!
+ .color,
+ ),
+ controller: logic.passwordTextController,
+ onEditingComplete: logic.focusNode.nextFocus,
+ ),
+ ),
+ Dimens.boxHeight40,
+ NxFilledButton(
+ onTap: () => logic.verifyPassword(),
+ label: StringValues.next.toUpperCase(),
+ ),
+ Dimens.boxHeight16,
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ );
+}
diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart
index bd0f8ff..414b65d 100644
--- a/lib/routes/app_pages.dart
+++ b/lib/routes/app_pages.dart
@@ -31,18 +31,24 @@ import 'package:social_media_app/modules/profile/bindings/edit_name_binding.dart
import 'package:social_media_app/modules/profile/bindings/edit_profession_binding.dart';
import 'package:social_media_app/modules/profile/bindings/edit_profile_picture_binding.dart';
import 'package:social_media_app/modules/profile/bindings/edit_username_binding.dart';
+import 'package:social_media_app/modules/profile/bindings/edit_website_binding.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_about_view.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_dob_view.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_gender_view.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_name_view.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_profession_view.dart';
import 'package:social_media_app/modules/profile/views/edit_views/edit_username_view.dart';
+import 'package:social_media_app/modules/profile/views/edit_views/edit_website_view.dart';
import 'package:social_media_app/modules/profile/views/profile_details_view.dart';
+import 'package:social_media_app/modules/settings/bindings/change_email_binding.dart';
import 'package:social_media_app/modules/settings/bindings/change_password_binding.dart';
+import 'package:social_media_app/modules/settings/bindings/change_phone_binding.dart';
import 'package:social_media_app/modules/settings/bindings/login_device_info_binding.dart';
import 'package:social_media_app/modules/settings/bindings/privacy_settings_binding.dart';
import 'package:social_media_app/modules/settings/bindings/setting_bindings.dart';
import 'package:social_media_app/modules/settings/views/pages/about_settings_view.dart';
+import 'package:social_media_app/modules/settings/views/pages/account/change_email_view.dart';
+import 'package:social_media_app/modules/settings/views/pages/account/change_phone_view.dart';
import 'package:social_media_app/modules/settings/views/pages/account_settings_view.dart';
import 'package:social_media_app/modules/settings/views/pages/help_settings_view.dart';
import 'package:social_media_app/modules/settings/views/pages/privacy/account_privacy_view.dart';
@@ -54,6 +60,8 @@ import 'package:social_media_app/modules/settings/views/pages/theme_settings_vie
import 'package:social_media_app/modules/settings/views/settings_view.dart';
import 'package:social_media_app/modules/user/user_details_binding.dart';
import 'package:social_media_app/modules/user/user_profile_view.dart';
+import 'package:social_media_app/modules/verify_password/verify_password_bindings.dart';
+import 'package:social_media_app/modules/verify_password/verify_password_view.dart';
import 'package:social_media_app/modules/welcome/welcome_view.dart';
part 'app_routes.dart';
@@ -183,6 +191,14 @@ abstract class AppPages {
transition: defaultTransition,
),
+ GetPage(
+ name: _Routes.editWebsite,
+ page: EditWebsiteView.new,
+ binding: EditWebsiteBinding(),
+ transitionDuration: transitionDuration,
+ transition: defaultTransition,
+ ),
+
/// ------------------------------------------------------------------------
/// Post Pages -------------------------------------------------------------
@@ -310,6 +326,26 @@ abstract class AppPages {
/// ------------------------------------------------------------------------
+ /// ACCOUNT SETTINGS -------------------------------------------------------
+
+ GetPage(
+ name: _Routes.changeEmailSettings,
+ page: ChangeEmailView.new,
+ transitionDuration: transitionDuration,
+ binding: ChangeEmailBinding(),
+ transition: defaultTransition,
+ ),
+
+ GetPage(
+ name: _Routes.changePhoneSettings,
+ page: ChangePhoneView.new,
+ transitionDuration: transitionDuration,
+ binding: ChangePhoneBinding(),
+ transition: defaultTransition,
+ ),
+
+ /// ------------------------------------------------------------------------
+
/// SECURITY SETTINGS -----------------------------------------------------
GetPage(
@@ -343,6 +379,7 @@ abstract class AppPages {
/// ------------------------------------------------------------------------
/// App Update -------------------------------------------------------------
+
GetPage(
name: _Routes.appUpdate,
page: AppUpdateView.new,
@@ -351,5 +388,17 @@ abstract class AppPages {
),
/// ------------------------------------------------------------------------
+
+ /// App Update -------------------------------------------------------------
+
+ GetPage(
+ name: _Routes.verifyPassword,
+ page: VerifyPasswordView.new,
+ binding: VerifyPasswordBinding(),
+ transitionDuration: transitionDuration,
+ transition: defaultTransition,
+ ),
+
+ /// ------------------------------------------------------------------------
];
}
diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart
index 4fcbcea..37373f2 100644
--- a/lib/routes/app_routes.dart
+++ b/lib/routes/app_routes.dart
@@ -37,6 +37,7 @@ abstract class AppRoutes {
static const verifyAccount = _Routes.verifyAccount;
static const sendVerifyEmailOtp = _Routes.sendVerifyEmailOtp;
static const verifyEmail = _Routes.verifyEmail;
+ static const verifyPassword = _Routes.verifyPassword;
static const editProfile = _Routes.editProfile;
static const editName = _Routes.editName;
@@ -103,6 +104,7 @@ abstract class _Routes {
static const verifyAccount = '/verify_account';
static const sendVerifyEmailOtp = '/send_email_verification_otp';
static const verifyEmail = '/verify_email';
+ static const verifyPassword = '/verify_password';
static const editProfile = '/edit_profile';
static const editName = '/edit_name';
diff --git a/lib/routes/route_management.dart b/lib/routes/route_management.dart
index f344015..c3d35a4 100644
--- a/lib/routes/route_management.dart
+++ b/lib/routes/route_management.dart
@@ -1,3 +1,4 @@
+import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:social_media_app/apis/models/entities/post.dart';
import 'package:social_media_app/modules/follower/controllers/followers_list_controller.dart';
@@ -75,6 +76,10 @@ abstract class RouteManagement {
Get.toNamed(AppRoutes.editProfession);
}
+ static void goToEditWebsiteView() {
+ Get.toNamed(AppRoutes.editWebsite);
+ }
+
/// --------------------------------------------------------------------------
/// Profile & User -----------------------------------------------------------
@@ -148,10 +153,14 @@ abstract class RouteManagement {
/// --------------------------------------------------------------------------
- /// Go to App Update View ----------------------------------------------------
+ /// Account Settings Pages --------------------------------------------------
- static void goToAppUpdateView() {
- Get.offAllNamed(AppRoutes.appUpdate);
+ static void goToChangeEmailSettingsView() {
+ Get.toNamed(AppRoutes.changeEmailSettings);
+ }
+
+ static void goToChangePhoneSettingsView() {
+ Get.toNamed(AppRoutes.changePhoneSettings);
}
/// --------------------------------------------------------------------------
@@ -176,6 +185,22 @@ abstract class RouteManagement {
/// --------------------------------------------------------------------------
+ /// Go to App Update View ----------------------------------------------------
+
+ static void goToAppUpdateView() {
+ Get.offAllNamed(AppRoutes.appUpdate);
+ }
+
+ /// --------------------------------------------------------------------------
+
+ /// Go to Verify Password View -----------------------------------------------
+
+ static void goToVerifyPasswordView(VoidCallback cb) {
+ Get.toNamed(AppRoutes.verifyPassword, arguments: cb);
+ }
+
+ /// --------------------------------------------------------------------------
+
/// Go to back Page / Close Pages --------------------------------------------
static void goToBack() {
diff --git a/lib/translations/app_translations.dart b/lib/translations/app_translations.dart
new file mode 100644
index 0000000..07e45bc
--- /dev/null
+++ b/lib/translations/app_translations.dart
@@ -0,0 +1,11 @@
+import 'package:get/get.dart';
+import 'package:social_media_app/translations/en_US/en_us_translations.dart';
+import 'package:social_media_app/translations/hi_IN/hi_in_translations.dart';
+
+class AppTranslation extends Translations {
+ @override
+ Map> get keys => {
+ 'en': enUs,
+ 'hi': hiIn,
+ };
+}
diff --git a/lib/translations/en_US/en_us_translations.dart b/lib/translations/en_US/en_us_translations.dart
new file mode 100644
index 0000000..872c6f8
--- /dev/null
+++ b/lib/translations/en_US/en_us_translations.dart
@@ -0,0 +1,4 @@
+final Map enUs = {
+ 'hi': 'Hi',
+ 'app_name': 'Rippl',
+};
diff --git a/lib/translations/hi_IN/hi_in_translations.dart b/lib/translations/hi_IN/hi_in_translations.dart
new file mode 100644
index 0000000..e4517ef
--- /dev/null
+++ b/lib/translations/hi_IN/hi_in_translations.dart
@@ -0,0 +1,4 @@
+final Map hiIn = {
+ 'hi': 'Hi',
+ 'app_name': 'Rippl',
+};
diff --git a/pubspec.lock b/pubspec.lock
index f3fc262..4420699 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -225,13 +225,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
- country_code_picker:
- dependency: "direct main"
- description:
- name: country_code_picker
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.2"
cross_file:
dependency: transitive
description:
@@ -372,6 +365,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
+ fl_country_code_picker:
+ dependency: "direct main"
+ description:
+ name: fl_country_code_picker
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.0.3"
flutter:
dependency: "direct main"
description: flutter
@@ -397,7 +397,7 @@ packages:
name: flutter_carousel_widget
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
flutter_datetime_picker:
dependency: "direct main"
description:
@@ -460,7 +460,7 @@ packages:
name: flutter_native_splash
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.8"
+ version: "2.2.9"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
@@ -582,7 +582,7 @@ packages:
name: get_time_ago
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.5"
+ version: "1.1.6"
glob:
dependency: transitive
description:
@@ -786,13 +786,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
- modal_bottom_sheet:
- dependency: transitive
- description:
- name: modal_bottom_sheet
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
octo_image:
dependency: transitive
description:
@@ -1024,6 +1017,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.27.5"
+ scrollable_positioned_list:
+ dependency: transitive
+ description:
+ name: scrollable_positioned_list
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.3"
share:
dependency: "direct main"
description:
@@ -1218,13 +1218,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
- universal_platform:
- dependency: transitive
- description:
- name: universal_platform
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0+1"
url_launcher:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 5a0ed01..a86963a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A social media app using Flutter, Dart, GetX, and REST API that all
publish_to: "none"
-version: 1.0.1+05
+version: 1.0.1+06
environment:
sdk: ">=2.17.0 <3.0.0"
@@ -23,12 +23,12 @@ dependencies:
image_cropper: ^3.0.0
cached_network_image: ^3.2.2
photo_view: ^0.14.0
- flutter_carousel_widget: ^1.1.0
+ flutter_carousel_widget: ^1.2.0
connectivity: ^3.0.6
http: ^0.13.5
intl: ^0.17.0
- get_time_ago: ^1.1.5
+ get_time_ago: ^1.1.6
cloudinary: ^1.0.0
r_upgrade: ^0.3.8+2
@@ -49,7 +49,7 @@ dependencies:
permission_handler: ^10.0.0
pattern_formatter: ^2.0.0
flutter_datetime_picker: ^1.5.1
- country_code_picker: ^2.0.2
+ fl_country_code_picker: ^0.0.3
get: ^4.6.5
get_storage: ^2.0.3
@@ -63,7 +63,7 @@ dev_dependencies:
flutter_lints: ^2.0.1
flutter_launcher_icons: ^0.10.0
- flutter_native_splash: ^2.2.8
+ flutter_native_splash: ^2.2.9
build_runner: ^2.2.0
json_serializable: ^6.3.1
diff --git a/web/index.html b/web/index.html
index 53a6d0b..b07cc38 100644
--- a/web/index.html
+++ b/web/index.html
@@ -1,6 +1,4 @@
-
-
-
+
-
+
social_media_app
-
+
-
-
-
-
-
+
+
+
+
+
+
@@ -108,5 +107,6 @@
loadMainDartJs();
}
-
-
+
+
+
\ No newline at end of file
diff --git a/web/splash/style.css b/web/splash/style.css
index 99491bb..6439e37 100644
--- a/web/splash/style.css
+++ b/web/splash/style.css
@@ -1,7 +1,7 @@
body {
margin:0;
height:100%;
- background: #F0F0F0;
+ background: #ECECEC;
background-size: 100% 100%;
}
@@ -56,7 +56,7 @@ body {
body {
margin:0;
height:100%;
- background: #1C1D31;
+ background: #12121E;
background-size: 100% 100%;
}