mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
ec065c0122 | |||
2960c6e59e |
@ -29,6 +29,7 @@ Features:
|
|||||||
- Download stories and comments for offline reading.
|
- Download stories and comments for offline reading.
|
||||||
- Pick up where you left off.
|
- Pick up where you left off.
|
||||||
- Synced favorites and pins across devices. (iOS only)
|
- Synced favorites and pins across devices. (iOS only)
|
||||||
|
- Export or import your favorites.
|
||||||
- Launch from system share sheet.
|
- Launch from system share sheet.
|
||||||
- And more...
|
- And more...
|
||||||
|
|
||||||
|
@ -27,12 +27,16 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- integration_test (0.0.1):
|
- integration_test (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- MTBBarcodeScanner (5.0.11)
|
||||||
- OrderedSet (5.0.0)
|
- OrderedSet (5.0.0)
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
- Flutter
|
- Flutter
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- qr_code_scanner (0.2.0):
|
||||||
|
- Flutter
|
||||||
|
- MTBBarcodeScanner
|
||||||
- ReachabilitySwift (5.0.0)
|
- ReachabilitySwift (5.0.0)
|
||||||
- receive_sharing_intent (0.0.1):
|
- receive_sharing_intent (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@ -68,6 +72,7 @@ DEPENDENCIES:
|
|||||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
|
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
|
||||||
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
@ -81,6 +86,7 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- FMDB
|
- FMDB
|
||||||
|
- MTBBarcodeScanner
|
||||||
- OrderedSet
|
- OrderedSet
|
||||||
- ReachabilitySwift
|
- ReachabilitySwift
|
||||||
|
|
||||||
@ -109,6 +115,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
|
qr_code_scanner:
|
||||||
|
:path: ".symlinks/plugins/qr_code_scanner/ios"
|
||||||
receive_sharing_intent:
|
receive_sharing_intent:
|
||||||
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||||
share_plus:
|
share_plus:
|
||||||
@ -140,9 +148,11 @@ SPEC CHECKSUMS:
|
|||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
|
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
|
||||||
integration_test: 13825b8a9334a850581300559b8839134b124670
|
integration_test: 13825b8a9334a850581300559b8839134b124670
|
||||||
|
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||||
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
||||||
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
|
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
|
||||||
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
||||||
|
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
|
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
|
||||||
share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028
|
share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028
|
||||||
|
@ -76,5 +76,9 @@
|
|||||||
<false/>
|
<false/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>This app needs camera access to scan QR codes</string>
|
||||||
|
<key>io.flutter.embedded_views_preview</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -11,10 +11,14 @@ class CustomRouter {
|
|||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
case HomeScreen.routeName:
|
case HomeScreen.routeName:
|
||||||
return HomeScreen.route();
|
return HomeScreen.route();
|
||||||
case ItemScreen.routeName:
|
|
||||||
return ItemScreen.route(settings.arguments! as ItemScreenArgs);
|
|
||||||
case SubmitScreen.routeName:
|
case SubmitScreen.routeName:
|
||||||
return SubmitScreen.route();
|
return SubmitScreen.route();
|
||||||
|
case QrCodeScannerScreen.routeName:
|
||||||
|
return QrCodeScannerScreen.route();
|
||||||
|
case ItemScreen.routeName:
|
||||||
|
return ItemScreen.route(settings.arguments! as ItemScreenArgs);
|
||||||
|
case QrCodeViewScreen.routeName:
|
||||||
|
return QrCodeViewScreen.route(data: settings.arguments! as String);
|
||||||
default:
|
default:
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
}
|
}
|
||||||
|
14
lib/models/export_destination.dart
Normal file
14
lib/models/export_destination.dart
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import 'package:flutter/material.dart' show IconData, Icons;
|
||||||
|
|
||||||
|
enum ExportDestination {
|
||||||
|
qrCode('QR code', icon: Icons.qr_code),
|
||||||
|
clipBoard('ClipBoard', icon: Icons.copy);
|
||||||
|
|
||||||
|
const ExportDestination(
|
||||||
|
this.label, {
|
||||||
|
required this.icon,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String label;
|
||||||
|
final IconData icon;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export 'comments_order.dart';
|
export 'comments_order.dart';
|
||||||
|
export 'export_destination.dart';
|
||||||
export 'fetch_mode.dart';
|
export 'fetch_mode.dart';
|
||||||
export 'font.dart';
|
export 'font.dart';
|
||||||
export 'font_size.dart';
|
export 'font_size.dart';
|
||||||
|
78
lib/screens/profile/qr_code_scanner_screen.dart
Normal file
78
lib/screens/profile/qr_code_scanner_screen.dart
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hacki/main.dart';
|
||||||
|
import 'package:hacki/styles/styles.dart';
|
||||||
|
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||||
|
|
||||||
|
class QrCodeScannerScreen extends StatefulWidget {
|
||||||
|
const QrCodeScannerScreen({super.key});
|
||||||
|
|
||||||
|
static const String routeName = '/qr-code-scanner';
|
||||||
|
|
||||||
|
static Route<dynamic> route() {
|
||||||
|
return MaterialPageRoute<String?>(
|
||||||
|
settings: const RouteSettings(name: routeName),
|
||||||
|
builder: (_) => const QrCodeScannerScreen(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QrCodeScannerScreen> createState() => _QrCodeScannerScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QrCodeScannerScreenState extends State<QrCodeScannerScreen> {
|
||||||
|
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
||||||
|
QRViewController? controller;
|
||||||
|
bool isFlashOn = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0,
|
||||||
|
backgroundColor: Palette.transparent,
|
||||||
|
actions: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(isFlashOn ? Icons.flash_off : Icons.flash_on),
|
||||||
|
onPressed: () {
|
||||||
|
controller?.toggleFlash();
|
||||||
|
setState(() {
|
||||||
|
isFlashOn = !isFlashOn;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.cameraswitch_outlined),
|
||||||
|
onPressed: controller?.flipCamera,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
body: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: QRView(
|
||||||
|
key: qrKey,
|
||||||
|
onQRViewCreated: onQRViewCreated,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onQRViewCreated(QRViewController controller) {
|
||||||
|
setState(() {
|
||||||
|
this.controller = controller;
|
||||||
|
});
|
||||||
|
controller.scannedDataStream.listen((Barcode scanData) {
|
||||||
|
controller.stopCamera();
|
||||||
|
HackiApp.navigatorKey.currentState?.pop(scanData.code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller?.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
55
lib/screens/profile/qr_code_view_screen.dart
Normal file
55
lib/screens/profile/qr_code_view_screen.dart
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hacki/styles/palette.dart';
|
||||||
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
|
||||||
|
class QrCodeViewScreen extends StatelessWidget {
|
||||||
|
const QrCodeViewScreen({
|
||||||
|
required this.data,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String data;
|
||||||
|
|
||||||
|
static const String routeName = '/qr-code-view';
|
||||||
|
|
||||||
|
static Route<dynamic> route({required String data}) {
|
||||||
|
return MaterialPageRoute<QrCodeViewScreen>(
|
||||||
|
settings: const RouteSettings(name: routeName),
|
||||||
|
builder: (_) => QrCodeViewScreen(
|
||||||
|
data: data,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int qrCodeVersion = 4;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0,
|
||||||
|
backgroundColor: Palette.transparent,
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Center(
|
||||||
|
child: QrImageView(
|
||||||
|
data: data,
|
||||||
|
dataModuleStyle: QrDataModuleStyle(
|
||||||
|
dataModuleShape: QrDataModuleShape.square,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
eyeStyle: QrEyeStyle(
|
||||||
|
eyeShape: QrEyeShape.square,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
version: qrCodeVersion,
|
||||||
|
size: 300,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||||
@ -14,9 +15,12 @@ import 'package:hacki/config/constants.dart';
|
|||||||
import 'package:hacki/config/locator.dart';
|
import 'package:hacki/config/locator.dart';
|
||||||
import 'package:hacki/cubits/cubits.dart';
|
import 'package:hacki/cubits/cubits.dart';
|
||||||
import 'package:hacki/extensions/extensions.dart';
|
import 'package:hacki/extensions/extensions.dart';
|
||||||
|
import 'package:hacki/main.dart';
|
||||||
import 'package:hacki/models/models.dart';
|
import 'package:hacki/models/models.dart';
|
||||||
import 'package:hacki/repositories/repositories.dart';
|
import 'package:hacki/repositories/repositories.dart';
|
||||||
import 'package:hacki/screens/profile/models/page_type.dart';
|
import 'package:hacki/screens/profile/models/page_type.dart';
|
||||||
|
import 'package:hacki/screens/profile/qr_code_scanner_screen.dart';
|
||||||
|
import 'package:hacki/screens/profile/qr_code_view_screen.dart';
|
||||||
import 'package:hacki/screens/profile/widgets/offline_list_tile.dart';
|
import 'package:hacki/screens/profile/widgets/offline_list_tile.dart';
|
||||||
import 'package:hacki/screens/profile/widgets/tab_bar_settings.dart';
|
import 'package:hacki/screens/profile/widgets/tab_bar_settings.dart';
|
||||||
import 'package:hacki/screens/widgets/widgets.dart';
|
import 'package:hacki/screens/widgets/widgets.dart';
|
||||||
@ -244,6 +248,13 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
onTap: onExportFavoritesTapped,
|
onTap: onExportFavoritesTapped,
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text(
|
||||||
|
'Import Favorites',
|
||||||
|
),
|
||||||
|
onTap: () =>
|
||||||
|
onImportFavoritesTapped(context.read<FavCubit>()),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text(
|
title: const Text(
|
||||||
'Clear Favorites',
|
'Clear Favorites',
|
||||||
@ -754,22 +765,70 @@ class _SettingsState extends State<Settings> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onExportFavoritesTapped() async {
|
Future<void> onExportFavoritesTapped() async {
|
||||||
final List<int> allFavorites = context.read<FavCubit>().state.favIds;
|
return showModalBottomSheet<ExportDestination>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
...ExportDestination.values.map(
|
||||||
|
(ExportDestination e) => ListTile(
|
||||||
|
leading: Icon(e.icon),
|
||||||
|
title: Text(e.label),
|
||||||
|
onTap: () => Navigator.pop<ExportDestination>(context, e),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).then(
|
||||||
|
(ExportDestination? destination) => exportFavorites(to: destination),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> onImportFavoritesTapped(FavCubit favCubit) async {
|
||||||
|
final String? res = await HackiApp.navigatorKey.currentState
|
||||||
|
?.pushNamed(QrCodeScannerScreen.routeName) as String?;
|
||||||
|
final List<int>? ids =
|
||||||
|
res?.split('\n').map(int.tryParse).whereType<int>().toList();
|
||||||
|
if (ids == null) return;
|
||||||
|
for (final int id in ids) {
|
||||||
|
await favCubit.addFav(id);
|
||||||
|
}
|
||||||
|
showSnackBar(content: 'Favorites imported successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> exportFavorites({required ExportDestination? to}) async {
|
||||||
|
final ExportDestination? destination = to;
|
||||||
|
if (destination == null) return;
|
||||||
|
|
||||||
|
final List<int> allFavorites = context.read<FavCubit>().state.favIds;
|
||||||
if (allFavorites.isEmpty) {
|
if (allFavorites.isEmpty) {
|
||||||
showSnackBar(content: "You don't have any favorite item.");
|
showSnackBar(content: "You don't have any favorite item.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final String allFavoritesStr = allFavorites.join('\n');
|
||||||
|
|
||||||
|
switch (destination) {
|
||||||
|
case ExportDestination.qrCode:
|
||||||
|
await HackiApp.navigatorKey.currentState?.pushNamed(
|
||||||
|
QrCodeViewScreen.routeName,
|
||||||
|
arguments: allFavoritesStr,
|
||||||
|
);
|
||||||
|
case ExportDestination.clipBoard:
|
||||||
try {
|
try {
|
||||||
await FlutterClipboard.copy(
|
await FlutterClipboard.copy(allFavoritesStr)
|
||||||
allFavorites.join('\n'),
|
.whenComplete(HapticFeedbackUtil.selection);
|
||||||
).whenComplete(HapticFeedbackUtil.selection);
|
showSnackBar(
|
||||||
showSnackBar(content: 'Ids of favorites have been copied to clipboard.');
|
content: 'Ids of favorites have been copied to clipboard.',
|
||||||
|
);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
error.logError(stackTrace: stackTrace);
|
error.logError(stackTrace: stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void showClearFavoritesDialog() {
|
void showClearFavoritesDialog() {
|
||||||
showDialog<bool>(
|
showDialog<bool>(
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
export 'home/home_screen.dart';
|
export 'home/home_screen.dart';
|
||||||
export 'item/item_screen.dart';
|
export 'item/item_screen.dart';
|
||||||
export 'profile/profile_screen.dart';
|
export 'profile/profile_screen.dart';
|
||||||
|
export 'profile/qr_code_scanner_screen.dart';
|
||||||
|
export 'profile/qr_code_view_screen.dart';
|
||||||
export 'search/search_screen.dart';
|
export 'search/search_screen.dart';
|
||||||
export 'submit/submit_screen.dart';
|
export 'submit/submit_screen.dart';
|
||||||
export 'web_view/web_view_screen.dart';
|
export 'web_view/web_view_screen.dart';
|
||||||
|
26
pubspec.lock
26
pubspec.lock
@ -840,6 +840,30 @@ packages:
|
|||||||
url: "https://github.com/livinglist/flutter_pulltorefresh"
|
url: "https://github.com/livinglist/flutter_pulltorefresh"
|
||||||
source: git
|
source: git
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
qr:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: qr
|
||||||
|
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
|
qr_code_scanner:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: qr_code_scanner
|
||||||
|
sha256: f23b68d893505a424f0bd2e324ebea71ed88465d572d26bb8d2e78a4749591fd
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
qr_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: qr_flutter
|
||||||
|
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
receive_sharing_intent:
|
receive_sharing_intent:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1390,4 +1414,4 @@ packages:
|
|||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.0.0 <4.0.0"
|
dart: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.10.3"
|
flutter: ">=3.10.5"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
name: hacki
|
name: hacki
|
||||||
description: A Hacker News reader.
|
description: A Hacker News reader.
|
||||||
version: 1.7.4+115
|
version: 1.8.0+116
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: "3.10.3"
|
flutter: "3.10.5"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
adaptive_theme: ^3.2.0
|
adaptive_theme: ^3.2.0
|
||||||
@ -58,6 +58,8 @@ dependencies:
|
|||||||
git:
|
git:
|
||||||
url: https://github.com/livinglist/flutter_pulltorefresh
|
url: https://github.com/livinglist/flutter_pulltorefresh
|
||||||
ref: master
|
ref: master
|
||||||
|
qr_code_scanner: ^1.0.1
|
||||||
|
qr_flutter: ^4.1.0
|
||||||
receive_sharing_intent: ^1.4.5
|
receive_sharing_intent: ^1.4.5
|
||||||
responsive_builder: ^0.7.0
|
responsive_builder: ^0.7.0
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
|
Submodule submodules/flutter updated: f92f44110e...796c8ef792
Reference in New Issue
Block a user