From b76436e3b10bd154cfa139f29eaa1b3c28a7d6f6 Mon Sep 17 00:00:00 2001 From: Felipe Bueno Date: Sun, 9 Jun 2024 20:17:52 -0300 Subject: [PATCH] Add Stacker Saloon --- lib/data/api.dart | 25 ++++++++++----- lib/data/shared_prefs_manager.dart | 6 ++-- lib/data/theme_notifier.dart | 4 +-- lib/utils.dart | 7 ++--- lib/views/pages/home_page.dart | 31 +----------------- lib/views/widgets/maybe_new_post_button.dart | 33 ++++++++++++++++++++ lib/views/widgets/post_item.dart | 18 ++++++----- lib/views/widgets/sn_endpoint_version.dart | 2 +- 8 files changed, 71 insertions(+), 55 deletions(-) create mode 100644 lib/views/widgets/maybe_new_post_button.dart diff --git a/lib/data/api.dart b/lib/data/api.dart index 9998e3a..98f692e 100644 --- a/lib/data/api.dart +++ b/lib/data/api.dart @@ -118,13 +118,24 @@ final class Api { ) async { final response = (responseData['pageProps'] ?? responseData); final data = response['ssrData'] ?? response['data']; + final itemsMap = (data['items'] ?? data['topItems'] ?? data['notifications']); final List items = itemsMap['items'] ?? itemsMap['notifications']; + if (postType == PostType.home) { + // TODO: Temporary solution to get Stacker Saloon on the list + final List? pins = itemsMap['pins']; + if (pins != null && pins.isNotEmpty) { + for (var pin in pins) { + items.insert(pin['position'], pin); + } + } + } + final cursor = itemsMap['cursor']; if (cursor != null) { - await SharedPrefsManager.create( + await SharedPrefsManager.set( '${postType.name}-cursor', cursor, ); @@ -169,15 +180,15 @@ final class Api { } Future _saveBuildId(String newBuildId) async { - await SharedPrefsManager.create('build-id', newBuildId); + await SharedPrefsManager.set('build-id', newBuildId); } Future _getCurrBuildId() async { - return await SharedPrefsManager.read('build-id'); + return await SharedPrefsManager.get('build-id'); } Future> fetchMorePosts(PostType postType) async { - final cursor = await SharedPrefsManager.read('${postType.name}-cursor'); + final cursor = await SharedPrefsManager.get('${postType.name}-cursor'); if (cursor == null) { throw Exception('Error fetching more'); @@ -249,7 +260,7 @@ final class Api { return null; } - await SharedPrefsManager.create( + await SharedPrefsManager.set( 'me', jsonEncode(me), ); @@ -365,7 +376,7 @@ final class Api { if (response.statusCode == 403 && response.realUri.toString() == '$baseUrl/api/auth/error?error=Verification') { - final sessionData = await SharedPrefsManager.read('session'); + final sessionData = await SharedPrefsManager.get('session'); if (sessionData == null || sessionData == 'null' || sessionData == '{}') { _goToLoginFailedPage(); @@ -401,7 +412,7 @@ final class Api { return null; } - await SharedPrefsManager.create( + await SharedPrefsManager.set( 'session', jsonEncode(sessionResponse.data), ); diff --git a/lib/data/shared_prefs_manager.dart b/lib/data/shared_prefs_manager.dart index 2867594..12d4311 100644 --- a/lib/data/shared_prefs_manager.dart +++ b/lib/data/shared_prefs_manager.dart @@ -1,7 +1,7 @@ import 'package:shared_preferences/shared_preferences.dart'; class SharedPrefsManager { - static Future create(String key, dynamic value) async { + static Future set(String key, dynamic value) async { final prefs = await SharedPreferences.getInstance(); if (value is int) { @@ -16,12 +16,12 @@ class SharedPrefsManager { prefs.setStringList(key, value); } else { print( - 'SharedPrefsManager.create error: value => $value for key => $key has unexpected type.', + 'SharedPrefsManager.set error: value => $value for key => $key has unexpected type.', ); } } - static Future read(String key) async { + static Future get(String key) async { final prefs = await SharedPreferences.getInstance(); return prefs.get(key); diff --git a/lib/data/theme_notifier.dart b/lib/data/theme_notifier.dart index 180da4e..d86566f 100644 --- a/lib/data/theme_notifier.dart +++ b/lib/data/theme_notifier.dart @@ -53,7 +53,7 @@ class ThemeNotifier with ChangeNotifier { } ThemeNotifier() { - SharedPrefsManager.read('theme-mode').then( + SharedPrefsManager.get('theme-mode').then( (value) { setThemeMode(value); @@ -81,7 +81,7 @@ class ThemeNotifier with ChangeNotifier { default: _themeData = ThemeMode.dark; } - SharedPrefsManager.create('theme-mode', themeMode); + SharedPrefsManager.set('theme-mode', themeMode); notifyListeners(); } diff --git a/lib/utils.dart b/lib/utils.dart index 16fff53..a5171fc 100644 --- a/lib/utils.dart +++ b/lib/utils.dart @@ -84,8 +84,7 @@ class Utils { } else if (await canLaunchUrl(uri)) { await launchUrl(uri); } else { - showError( - 'Could not launch $url. Make sure you have a web browser installed'); + showError('Could not launch $url'); return; } @@ -100,7 +99,7 @@ class Utils { return; } - // TODO: We should check if the modal is open before popping + // TODO: We should check if the modal is open before popping it if (Navigator.of(ctx).canPop()) { Navigator.of(ctx).pop(); } @@ -218,7 +217,7 @@ class Utils { } static Future getSession() async { - final sessionData = await SharedPrefsManager.read('session'); + final sessionData = await SharedPrefsManager.get('session'); if (sessionData == null || sessionData == 'null' || sessionData == '{}') { return null; diff --git a/lib/views/pages/home_page.dart b/lib/views/pages/home_page.dart index 5773deb..178bfd8 100644 --- a/lib/views/pages/home_page.dart +++ b/lib/views/pages/home_page.dart @@ -7,11 +7,11 @@ import 'package:stacker_news/data/models/session.dart'; import 'package:stacker_news/main.dart'; import 'package:stacker_news/utils.dart'; import 'package:stacker_news/views/pages/auth/sign_in_page.dart'; -import 'package:stacker_news/views/pages/new_post/new_post_page.dart'; import 'package:stacker_news/views/pages/notifications/notifications_page.dart'; import 'package:stacker_news/views/pages/profile/profile_page.dart'; import 'package:stacker_news/views/widgets/base_tab.dart'; import 'package:stacker_news/views/widgets/generic_page_scaffold.dart'; +import 'package:stacker_news/views/widgets/maybe_new_post_button.dart'; import 'package:stacker_news/views/widgets/sn_logo.dart'; class HomePage extends StatelessWidget { @@ -141,32 +141,3 @@ class _MaybeNotificationsButtonState extends State { ); } } - -class MaybeNewPostFab extends StatefulWidget { - const MaybeNewPostFab({super.key}); - - @override - State createState() => _MaybeNewPostFabState(); -} - -class _MaybeNewPostFabState extends State { - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: Utils.getSession(), - builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data is Session) { - return FloatingActionButton.extended( - onPressed: () { - Navigator.pushNamed(context, NewPostPage.id); - }, - icon: const Icon(Icons.add), - label: const Text('New Post'), - ); - } - - return Container(); - }, - ); - } -} diff --git a/lib/views/widgets/maybe_new_post_button.dart b/lib/views/widgets/maybe_new_post_button.dart new file mode 100644 index 0000000..51f503c --- /dev/null +++ b/lib/views/widgets/maybe_new_post_button.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:stacker_news/data/models/session.dart'; +import 'package:stacker_news/utils.dart'; +import 'package:stacker_news/views/pages/new_post/new_post_page.dart'; + +class MaybeNewPostFab extends StatefulWidget { + const MaybeNewPostFab({super.key}); + + @override + State createState() => _MaybeNewPostFabState(); +} + +class _MaybeNewPostFabState extends State { + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: Utils.getSession(), + builder: (context, snapshot) { + if (snapshot.hasData && snapshot.data is Session) { + return FloatingActionButton.extended( + onPressed: () { + Navigator.pushNamed(context, NewPostPage.id); + }, + icon: const Icon(Icons.add), + label: const Text('New Post'), + ); + } + + return Container(); + }, + ); + } +} diff --git a/lib/views/widgets/post_item.dart b/lib/views/widgets/post_item.dart index 944b328..4a0cdfe 100644 --- a/lib/views/widgets/post_item.dart +++ b/lib/views/widgets/post_item.dart @@ -50,8 +50,9 @@ class _PostItemState extends State { arguments: _post, ); }, - child: Padding( + child: Container( padding: const EdgeInsets.symmetric(horizontal: 4.0), + color: item.position == null ? null : SNColors.primary.withOpacity(.27), child: Row( children: [ if (widget.isCommentsPage && item.id != null && item.id != '') @@ -127,14 +128,15 @@ class _PostItemState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Flexible( - child: Text( - item.isJob == true - ? '${item.company}' - : '${item.sats} sats', - style: label, + if (item.position == null) + Flexible( + child: Text( + item.isJob == true + ? '${item.company}' + : '${item.sats} sats', + style: label, + ), ), - ), Text( item.isJob == true ? '${(item.remote == true && item.location == '') ? 'Remote' : item.location}' diff --git a/lib/views/widgets/sn_endpoint_version.dart b/lib/views/widgets/sn_endpoint_version.dart index ee6ce2f..89444f0 100644 --- a/lib/views/widgets/sn_endpoint_version.dart +++ b/lib/views/widgets/sn_endpoint_version.dart @@ -5,7 +5,7 @@ class SNEndpointVersion extends StatelessWidget { const SNEndpointVersion({super.key}); Future _getVersion() async => - await SharedPrefsManager.read('build-id') ?? 'Unknown'; + await SharedPrefsManager.get('build-id') ?? 'Unknown'; @override Widget build(BuildContext context) {