Skip to content

Commit

Permalink
Merge pull request #12 from ecency/nt/welcome-with-terms
Browse files Browse the repository at this point in the history
Nt/welcome with terms
  • Loading branch information
feruzm authored Sep 5, 2024
2 parents e0d816e + d59f024 commit d832b58
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 14 deletions.
2 changes: 1 addition & 1 deletion lib/core/dependency_injection/get_it/services_get_it.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ServicesGetIt extends GetItFeature {
void featureInit() {
getIt.registerLazySingleton<ApiService>(() => ApiService());
getIt.registerLazySingleton<UserLocalService>(
() => UserLocalService(secureStorage: getIt.call()));
() => UserLocalService(secureStorage: getIt.call(), getStorage: getIt.call()));
getIt.registerLazySingleton<LocalService>(
() => LocalService(getStorage: getIt.call()));
}
Expand Down
44 changes: 35 additions & 9 deletions lib/core/routes/app_router.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:waves/core/routes/route_keys.dart';
import 'package:waves/core/routes/routes.dart';
import 'package:waves/core/services/user_local_service.dart';
import 'package:waves/core/utilities/enum.dart';
import 'package:waves/features/auth/presentation/view/auth_view.dart';
import 'package:waves/features/auth/presentation/view/hive_auth_transaction_view.dart';
import 'package:waves/features/auth/presentation/view/hive_key_chain_auth_view.dart';
import 'package:waves/features/auth/presentation/view/hive_signer_auth_view.dart';
import 'package:waves/features/auth/presentation/view/posting_key_auth_view.dart';
import 'package:waves/features/bookmarks/views/thread_bookmark/bookmark_view.dart';
import 'package:waves/features/settings/presentation/setting/controller/settings_controller.dart';
import 'package:waves/features/settings/presentation/setting/view/setting_view.dart';
import 'package:waves/features/threads/models/comment/comment_navigation_model.dart';
import 'package:waves/features/threads/models/thread_feeds/thread_feed_model.dart';
Expand All @@ -17,15 +20,32 @@ import 'package:waves/features/threads/presentation/comments/add_comment/view/hi
import 'package:waves/features/threads/presentation/comments/comment_detail/view/comment_detail_view.dart';
import 'package:waves/features/threads/presentation/thread_feed/view/thread_feed_view.dart';
import 'package:waves/features/user/presentation/user_profile/view/user_profile_view.dart';
import 'package:waves/features/user/repository/user_local_repository.dart';
import 'package:waves/features/user/view/user_controller.dart';
import 'package:waves/features/welcome/view/welcome_view.dart';

class AppRouter {
static final _rootNavigatorKey = GlobalKey<NavigatorState>();

static GoRouter router = GoRouter(
navigatorKey: _rootNavigatorKey, initialLocation: '/', routes: routes());
static GoRouter router(BuildContext context) {
bool isTermsAccepted = context.select<UserController, bool>(
(settingsController) => settingsController.getTermsAcceptedFlag());

String initialPath = isTermsAccepted ? '/' : '/${Routes.welcomeView}';

return GoRouter(
navigatorKey: _rootNavigatorKey,
initialLocation: initialPath,
routes: routes());
}

static List<RouteBase> routes() {
return [
GoRoute(
path: '/${Routes.welcomeView}',
name: Routes.welcomeView,
builder: (context, state) => const WelcomeView(),
),
GoRoute(
path: '/',
name: Routes.initialView,
Expand Down Expand Up @@ -85,18 +105,20 @@ class AppRouter {
);
},
),
GoRoute(
GoRoute(
path: '/${Routes.postingKeyAuthView}',
name: Routes.postingKeyAuthView,
builder: (context, state) {
return const PostingKeyAuthView();
},
),
GoRoute(
GoRoute(
path: '/${Routes.hiveKeyChainAuthView}',
name: Routes.hiveKeyChainAuthView,
builder: (context, state) {
return HiveKeyChainAuthView(authType:state.extra as AuthType ,);
return HiveKeyChainAuthView(
authType: state.extra as AuthType,
);
},
),
GoRoute(
Expand Down Expand Up @@ -131,16 +153,20 @@ class AppRouter {
return value.toLowerCase() == "true";
}

static String currentRoute() {
return AppRouter.router.routerDelegate.currentConfiguration.uri.path
static String currentRoute(BuildContext context) {
return AppRouter.router(context).routerDelegate.currentConfiguration.uri.path
.toString();
}

static void popTillFirstScreen(
BuildContext context,
) {
while (router
.routerDelegate.currentConfiguration.matches.last.matchedLocation !=
while ((router(context))
.routerDelegate
.currentConfiguration
.matches
.last
.matchedLocation !=
'/') {
if (!context.canPop()) {
return;
Expand Down
1 change: 1 addition & 0 deletions lib/core/routes/routes.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Routes {
static const String welcomeView = 'welcome';
static const String initialView = 'initial';
static const String homeView = 'home';
static const String bookmarksView = 'bookmarks';
Expand Down
20 changes: 18 additions & 2 deletions lib/core/services/user_local_service.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:get_storage/get_storage.dart';
import 'package:waves/core/utilities/enum.dart';
import 'package:waves/features/auth/models/hive_auth_model.dart';
import 'package:waves/features/auth/models/hive_signer_auth_model.dart';
Expand All @@ -8,10 +9,13 @@ import 'package:waves/features/auth/models/user_auth_model.dart';
class UserLocalService {
static const String _currentUserAccountStorageKey = 'currentUserAccount';
static const String _allUserAccountsStorageKey = 'allUserAccounts';
static const String _termsAcceptedFlagKey = 'termsAcceptedFlag';

final FlutterSecureStorage _secureStorage;
final GetStorage _getStorage;

UserLocalService({required FlutterSecureStorage secureStorage})
: _secureStorage = secureStorage;
UserLocalService({required FlutterSecureStorage secureStorage, required final GetStorage getStorage})
: _secureStorage = secureStorage, _getStorage = getStorage;

Future<void> cleanup() async {
await _secureStorage.delete(key: _currentUserAccountStorageKey);
Expand Down Expand Up @@ -79,4 +83,16 @@ class UserLocalService {
Future<void> logOut() async {
await _secureStorage.delete(key: _currentUserAccountStorageKey);
}


Future<void> writeTermsAcceptedFlag(bool status) async {
await _getStorage.write(_termsAcceptedFlagKey, status);
}

bool readTermsAcceptedFlag() {

bool? data = _getStorage.read(_termsAcceptedFlagKey);
return data ?? false;
}

}
10 changes: 10 additions & 0 deletions lib/features/user/repository/user_local_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ class UserLocalRepository {
Future<void> writeAllUserAccounts(List<UserAuthModel> accounts) async {
return await _localService.writeAllUserAccounts(accounts);
}

bool readTermsAcceptedFlag() {
return _localService.readTermsAcceptedFlag();
}

Future<void> writeTermsAcceptedFlag(bool status) async {
return await _localService.writeTermsAcceptedFlag(status);
}


}
8 changes: 8 additions & 0 deletions lib/features/user/view/user_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ class UserController extends ChangeNotifier {
_userSteamController.add(null);
}

bool getTermsAcceptedFlag() {
return _localRepository.readTermsAcceptedFlag();
}

void setTermsAcceptedFlag(bool status) async {
await _localRepository.writeTermsAcceptedFlag(status);
}

@override
void dispose() {
_userAuthSubscription.cancel();
Expand Down
193 changes: 193 additions & 0 deletions lib/features/welcome/view/welcome_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:waves/core/routes/routes.dart';
import 'package:waves/core/utilities/act.dart';
import 'package:waves/features/user/view/user_controller.dart';

class WelcomeView extends StatefulWidget {
const WelcomeView({super.key});

@override
_WelcomeViewState createState() => _WelcomeViewState();
}

class _WelcomeViewState extends State<WelcomeView> {
bool showAnimation = true;
bool isConsentChecked = false;
String appVersion =
"1.0.0"; // Flutter has no direct equivalent for getting version, use package_info for this

@override
void initState() {
super.initState();
}

void _handleButtonPress() {
context.read<UserController>().setTermsAcceptedFlag(true);

// Navigate to Main Screen (Use your route navigation logic here)
context.pushReplacementNamed(Routes.initialView);
}

void _onCheckPress(bool? value) {
setState(() {
isConsentChecked = value ?? false;
});
}

void _onTermsPress() {
// Navigate to a webview or open URL in browser
Act.launchThisUrl("https://ecency.com/terms-of-service");
}

Widget _renderInfo(IconData iconName, String heading, String body) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, // Aligns items at the top
children: [
Icon(iconName, size: 30, color: Colors.blue),
const SizedBox(width: 10),
Expanded(
// Ensures the column takes the available space and allows wrapping
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
heading,
style: const TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 5), // Add some spacing between heading and body
Text(
body,
style: const TextStyle(fontSize: 15),
softWrap: true, // Allows wrapping onto multiple lines
overflow: TextOverflow
.visible, // Ensure text remains visible if it exceeds space
),
],
),
),
],
),
);
}

Widget _renderConsent() {
return Row(
children: [
Checkbox.adaptive(
value: isConsentChecked,
onChanged: _onCheckPress,
),
Expanded(
child: GestureDetector(
onTap: _onTermsPress,
child: Text.rich(
TextSpan(
text: "I accept the ",
style: const TextStyle(fontSize: 14),
children: [
TextSpan(
text: "Terms and Conditions",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
),
),
],
),
),
),
),
],
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Waves', // Replace with localized text
style: TextStyle(fontSize: 34),
textAlign: TextAlign.start,
),
const Text(
'In Ocean of Thoughts', // Replace with localized text
style: TextStyle(
fontSize: 20,
),
),
Text(
'Short content sharing', // Replace with localized text
style: TextStyle(
fontSize: 34,
color: Theme.of(context).primaryColor),
),
],
),
),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Column(
children: [
_renderInfo(Icons.lock, 'Own Your Content',
'Post short blogs on a decentralized platform.'),
_renderInfo(
Icons.sentiment_satisfied_alt,
'Engage with Diverse Communities',
'Connect with a global community of content creators.'),
_renderInfo(Icons.speed, 'Post in Seconds',
'Share quickly using our simple, fast interface.'),
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
_renderConsent(),
const SizedBox(height: 20),
ElevatedButton(
onPressed: isConsentChecked ? _handleButtonPress : null,
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 30, vertical: 15),
),
child: const Text(
'Get Started', // Replace with localized text
style: TextStyle(fontSize: 16),
),
),
],
),
),
],
),
],
),
),
);
}
}
4 changes: 2 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void main() async {
if (packageInfo.version == "1.0.0" && packageInfo.buildNumber == "9") {
var isCleanUpDone = GetStorage().read('did_we_clean_up') as String? ?? 'no';
if (isCleanUpDone == "no") {
await UserLocalService(secureStorage: const FlutterSecureStorage()).cleanup();
await UserLocalService(secureStorage: const FlutterSecureStorage(), getStorage: GetStorage()).cleanup();
await GetStorage().write('did_we_clean_up', 'yes');
}
}
Expand All @@ -43,7 +43,7 @@ class MyApp extends StatelessWidget {
child: Consumer<ThemeController>(
builder: (context, themeController, child) {
return MaterialApp.router(
routerConfig: AppRouter.router,
routerConfig: AppRouter.router(context),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
Expand Down

0 comments on commit d832b58

Please sign in to comment.