diff --git a/assets/ic_flash_off_white_48dp.png b/assets/ic_flash_off_white_48dp.png
deleted file mode 100644
index 93a2626..0000000
Binary files a/assets/ic_flash_off_white_48dp.png and /dev/null differ
diff --git a/assets/ic_flash_on_white_48dp.png b/assets/ic_flash_on_white_48dp.png
deleted file mode 100644
index c9a3539..0000000
Binary files a/assets/ic_flash_on_white_48dp.png and /dev/null differ
diff --git a/assets/scan/flashlightOff.svg b/assets/scan/flashlightOff.svg
new file mode 100644
index 0000000..4b8de8e
--- /dev/null
+++ b/assets/scan/flashlightOff.svg
@@ -0,0 +1,33 @@
+
diff --git a/assets/scan/flashlightOn.svg b/assets/scan/flashlightOn.svg
new file mode 100644
index 0000000..e46c693
--- /dev/null
+++ b/assets/scan/flashlightOn.svg
@@ -0,0 +1,33 @@
+
diff --git a/assets/scan/showMore.svg b/assets/scan/showMore.svg
new file mode 100644
index 0000000..b3f1efa
--- /dev/null
+++ b/assets/scan/showMore.svg
@@ -0,0 +1,8 @@
+
diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart
index 5d5a61c..1c0002d 100644
--- a/lib/i18n/strings.g.dart
+++ b/lib/i18n/strings.g.dart
@@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang`
///
/// Locales: 1
-/// Strings: 22
+/// Strings: 28
///
-/// Built on 2024-08-21 at 08:34 UTC
+/// Built on 2024-09-24 at 17:35 UTC
// coverage:ignore-file
// ignore_for_file: type=lint
@@ -199,6 +199,12 @@ class _StringsScanEn {
// Translations
String get scanning => 'Skanowanie';
+ String get tryAgain => 'Niestety nie udało się pobrać danych. Spróbuj ponownie.';
+ String get pkt => ' pkt';
+ String get wait => 'Proszę czekać, trwa Ładowanie...';
+ String get lastScans => 'Ostatnie skany:';
+ String get error => 'Wystąpił błąd';
+ String get closeError => 'Zamknij.';
}
/// Flat map(s) containing all translations.
@@ -229,6 +235,12 @@ extension on Translations {
case 'companyScreen.companyFriend': return ' Ta firma jest przyjacielem Poli';
case 'companyScreen.polaFriends': return 'Przyjaciele Poli';
case 'scan.scanning': return 'Skanowanie';
+ case 'scan.tryAgain': return 'Niestety nie udało się pobrać danych. Spróbuj ponownie.';
+ case 'scan.pkt': return ' pkt';
+ case 'scan.wait': return 'Proszę czekać, trwa Ładowanie...';
+ case 'scan.lastScans': return 'Ostatnie skany:';
+ case 'scan.error': return 'Wystąpił błąd';
+ case 'scan.closeError': return 'Zamknij.';
default: return null;
}
}
diff --git a/lib/i18n/strings.i18n.json b/lib/i18n/strings.i18n.json
index 71b4726..71a16a8 100644
--- a/lib/i18n/strings.i18n.json
+++ b/lib/i18n/strings.i18n.json
@@ -25,6 +25,13 @@
"polaFriends": "Przyjaciele Poli"
},
"scan": {
- "scanning": "Skanowanie"
+ "scanning": "Skanowanie",
+ "tryAgain": "Niestety nie udało się pobrać danych. Spróbuj ponownie.",
+ "pkt":" pkt",
+ "wait": "Proszę czekać, trwa Ładowanie...",
+ "lastScans": "Ostatnie skany:",
+ "error": "Wystąpił błąd",
+ "closeError": "Zamknij."
}
+
}
diff --git a/lib/main.dart b/lib/main.dart
index 2a16e46..5e18481 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -70,22 +70,15 @@ class _PolaAppState extends State {
body: IndexedStack(
index: _selectedIndex,
children: _tabs,
- )
- ),
+ )),
),
);
}
final List _tabs = [
MainPage(),
- WebViewTab(
- title: "Wyszukiwarka",
- url: "https://www.pola-app.pl/m/search/"
- ),
- WebViewTab(
- title: "Wiadomości",
- url: "https://www.pola-app.pl/m/blog/"
- )
+ WebViewTab(title: "Wyszukiwarka", url: "https://www.pola-app.pl/m/search/"),
+ WebViewTab(title: "Wiadomości", url: "https://www.pola-app.pl/m/blog/")
];
AnalyticsMainTab _getTabParameter(int index) {
diff --git a/lib/pages/scan/companies_list.dart b/lib/pages/scan/companies_list.dart
index f3ecb45..b3c8199 100644
--- a/lib/pages/scan/companies_list.dart
+++ b/lib/pages/scan/companies_list.dart
@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:pola_flutter/analytics/pola_analytics.dart';
+import 'package:pola_flutter/i18n/strings.g.dart';
import 'package:pola_flutter/pages/scan/remote_button.dart';
import 'package:pola_flutter/pages/scan/scan_state.dart';
+import 'package:pola_flutter/theme/text_size.dart';
import 'package:pola_flutter/ui/list_item.dart';
+import 'dart:math';
class CompaniesList extends StatelessWidget {
CompaniesList(this.state, this.listScrollController);
@@ -13,35 +16,48 @@ class CompaniesList extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final int listSize = state.list.length;
+
_scrollToTop();
- return Column(mainAxisAlignment: MainAxisAlignment.end, children: [
- Container(
- height: 200,
- child: Align(
- alignment: Alignment.bottomCenter,
- child: ListView.builder(
- controller: listScrollController,
- reverse: true,
- itemCount: state.list.length + (state.isLoading ? 1 : 0),
- itemBuilder: (BuildContext context, int index) {
- if (index == state.list.length) {
- return LoadingListItem();
- }
- return GestureDetector(
- child: ResultListItem(state.list[index]),
- onTap: () {
- final result = state.list[index];
- _analytics.opensCard(result);
- Navigator.pushNamed(context, '/detail', arguments: result);
- },
- );
- },
+
+ double maxHeight = min(listSize * 47.5, 190.0);
+
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ _ListHeader(listSize: listSize),
+ Container(
+ constraints: BoxConstraints(
+ maxHeight: maxHeight,
+ ),
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: ListView.builder(
+ controller: listScrollController,
+ reverse: true,
+ itemCount: listSize + (state.isLoading ? 1 : 0),
+ itemBuilder: (BuildContext context, int index) {
+ if (index == listSize) {
+ return LoadingListItem();
+ }
+ return GestureDetector(
+ child: ResultListItem(state.list[index]),
+ onTap: () {
+ final result = state.list[index];
+ _analytics.opensCard(result);
+ Navigator.pushNamed(context, '/detail', arguments: result);
+ },
+ );
+ },
+ ),
),
),
- ),
- RemoteButton(RemoteButtonState(
- state.list.firstOrNull?.donate, state.list.firstOrNull?.code))
- ]);
+ RemoteButton(RemoteButtonState(
+ state.list.firstOrNull?.donate,
+ state.list.firstOrNull?.code,
+ )),
+ ],
+ );
}
void _scrollToTop() {
@@ -53,3 +69,31 @@ class CompaniesList extends StatelessWidget {
});
}
}
+
+class _ListHeader extends StatelessWidget {
+ final int listSize;
+
+ const _ListHeader({required this.listSize});
+
+ @override
+ Widget build(BuildContext context) {
+ if (listSize > 0) {
+ return Padding(
+ padding: const EdgeInsets.only(left: 16.0),
+ child: Align(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ t.scan.lastScans,
+ style: TextStyle(
+ fontSize: TextSize.mediumTitle,
+ fontWeight: FontWeight.bold,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ );
+ } else {
+ return Container();
+ }
+ }
+}
diff --git a/lib/pages/scan/scan.dart b/lib/pages/scan/scan.dart
index d6141ef..9589e27 100644
--- a/lib/pages/scan/scan.dart
+++ b/lib/pages/scan/scan.dart
@@ -29,6 +29,7 @@ class _MainPageState extends State {
final PolaAnalytics _analytics = PolaAnalytics.instance();
ScrollController listScrollController = ScrollController();
+ bool _isTorchOn = false;
@override
void initState() {
@@ -46,10 +47,9 @@ class _MainPageState extends State {
onPressed: () {
_analytics.aboutPolaOpened();
showWebViewDialog(
- context: context,
- url: "https://www.pola-app.pl/m/about",
- title: t.menu.aboutPola
- );
+ context: context,
+ url: "https://www.pola-app.pl/m/about",
+ title: t.menu.aboutPola);
},
icon: Assets.icLauncher.image(),
),
@@ -87,55 +87,82 @@ class _MainPageState extends State {
child: Column(
children: [
Center(
- child: Padding(
- padding: const EdgeInsets.only(top: 20.0),
- child: Text(
- "Umieść kod kreskowy produktu w prostokącie powyżej aby dowiedzieć się więcej o firmie, która go wyprodukowała.",
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- )))),
+ child: Padding(
+ padding: const EdgeInsets.only(top: 20.0),
+ child: Text(
+ "Umieść kod kreskowy produktu w prostokącie powyżej aby dowiedzieć się więcej o firmie, która go wyprodukowała.",
+ textAlign: TextAlign.center,
+ style: TextStyle(color: Colors.white),
+ ),
+ ),
+ ),
],
),
),
SafeArea(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- Spacer(),
- BlocBuilder(
- bloc: _scanBloc,
- builder: (context, state) {
- if (state.isError) {
- SchedulerBinding.instance.addPostFrameCallback((_) {
- showDialog(
- context: context,
- barrierDismissible: false,
- builder: (_) {
- return AlertDialog(
- title: Text('Wystąpił błąd'),
- content: Text('Niestety nie udało się pobrać danych. Spróbuj ponownie.'),
- actions: [
- TextButton(
- child: Text('Zamknij.'),
- onPressed: () {
- _scanBloc.add(ScanEvent.alertDialogDismissed());
- SchedulerBinding.instance.addPostFrameCallback((_) {
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Spacer(),
+ BlocBuilder(
+ bloc: _scanBloc,
+ builder: (context, state) {
+ if (state.isError) {
+ SchedulerBinding.instance.addPostFrameCallback((_) {
+ showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: Text(t.scan.error),
+ content: Text(t.scan.tryAgain),
+ actions: [
+ TextButton(
+ child: Text(t.scan.closeError),
+ onPressed: () {
+ _scanBloc
+ .add(ScanEvent.alertDialogDismissed());
Navigator.pop(context);
- });
- },
+ },
+ ),
+ ],
+ );
+ },
+ );
+ });
+ }
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Expanded(
+ child: CompaniesList(state, listScrollController)),
+ Column(
+ children: [
+ GestureDetector(
+ onTap: () {
+ setState(() {
+ _isTorchOn = !_isTorchOn;
+ cameraController.toggleTorch();
+ });
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ boxShadow: [],
+ ),
+ child: _isTorchOn
+ ? Assets.scan.flashlightOn.svg()
+ : Assets.scan.flashlightOff.svg(),
),
- ],
- );
- },
- );
- });
- }
- return CompaniesList(state, listScrollController);
- },
- ),
- ],
- )),
+ )
+ ],
+ )
+ ],
+ );
+ },
+ ),
+ ],
+ ),
+ ),
],
),
extendBodyBehindAppBar: true,
@@ -151,15 +178,16 @@ class _MainPageState extends State {
children: [
Positioned.fill(
child: MobileScanner(
- controller: cameraController,
- onDetect: (capture) {
- final List barcodes = capture.barcodes;
- for (final barcode in barcodes) {
- final String code = barcode.rawValue!;
- debugPrint('Barcode found! $code');
- _scanBloc.add(ScanEvent.barcodeScanned(code));
- }
- }),
+ controller: cameraController,
+ onDetect: (capture) {
+ final List barcodes = capture.barcodes;
+ for (final barcode in barcodes) {
+ final String code = barcode.rawValue!;
+ debugPrint('Barcode found! $code');
+ _scanBloc.add(ScanEvent.barcodeScanned(code));
+ }
+ },
+ ),
),
Positioned.fill(
child: Align(
diff --git a/lib/theme/assets.gen.dart b/lib/theme/assets.gen.dart
index d79e809..133472d 100644
--- a/lib/theme/assets.gen.dart
+++ b/lib/theme/assets.gen.dart
@@ -72,6 +72,22 @@ class $AssetsNavigationGen {
List get values => [close];
}
+class $AssetsScanGen {
+ const $AssetsScanGen();
+
+ /// File path: assets/scan/flashlightOff.svg
+ SvgGenImage get flashlightOff => const SvgGenImage('assets/scan/flashlightOff.svg');
+
+ /// File path: assets/scan/flashlightOn.svg
+ SvgGenImage get flashlightOn => const SvgGenImage('assets/scan/flashlightOn.svg');
+
+ /// File path: assets/scan/showMore.svg
+ SvgGenImage get showMore => const SvgGenImage('assets/scan/showMore.svg');
+
+ /// List of all assets
+ List get values => [flashlightOff, flashlightOn, showMore];
+}
+
class Assets {
Assets._();
@@ -80,24 +96,15 @@ class Assets {
static const AssetGenImage icBackspaceWhite36dp = AssetGenImage('assets/ic_backspace_white_36dp.png');
static const AssetGenImage icDialpadWhite36dp = AssetGenImage('assets/ic_dialpad_white_36dp.png');
static const AssetGenImage icDoneWhite36dp = AssetGenImage('assets/ic_done_white_36dp.png');
- static const AssetGenImage icFlashOffWhite48dp = AssetGenImage('assets/ic_flash_off_white_48dp.png');
- static const AssetGenImage icFlashOnWhite48dp = AssetGenImage('assets/ic_flash_on_white_48dp.png');
static const AssetGenImage icLauncher = AssetGenImage('assets/ic_launcher.png');
static const AssetGenImage menu = AssetGenImage('assets/menu.png');
static const $AssetsMenuPageGen menuPage = $AssetsMenuPageGen();
static const $AssetsNavigationGen navigation = $AssetsNavigationGen();
+ static const $AssetsScanGen scan = $AssetsScanGen();
/// List of all assets
- static List get values => [
- icAddBlack24dp,
- icBackspaceWhite36dp,
- icDialpadWhite36dp,
- icDoneWhite36dp,
- icFlashOffWhite48dp,
- icFlashOnWhite48dp,
- icLauncher,
- menu
- ];
+ static List get values =>
+ [icAddBlack24dp, icBackspaceWhite36dp, icDialpadWhite36dp, icDoneWhite36dp, icLauncher, menu];
}
class AssetGenImage {
diff --git a/lib/ui/list_item.dart b/lib/ui/list_item.dart
index e9653d9..6d74364 100644
--- a/lib/ui/list_item.dart
+++ b/lib/ui/list_item.dart
@@ -1,42 +1,83 @@
import 'package:flutter/material.dart';
+import 'package:pola_flutter/i18n/strings.g.dart';
import 'package:pola_flutter/models/search_result.dart';
+import 'package:pola_flutter/theme/assets.gen.dart';
+import 'package:pola_flutter/theme/colors.dart';
+import 'package:pola_flutter/theme/fonts.gen.dart';
import 'package:pola_flutter/theme/text_size.dart';
class ResultListItem extends StatelessWidget {
ResultListItem(this.searchResult);
final SearchResult searchResult;
+ static const double leftBoxSize = 40.0;
@override
Widget build(BuildContext context) {
- final textStyle = TextStyle(fontWeight: FontWeight.normal, fontSize: TextSize.mediumTitle);
+ final pointValueStyle = TextStyle(
+ height: 0,
+ fontWeight: FontWeight.w700,
+ fontFamily: FontFamily.roboto,
+ fontSize: TextSize.mediumTitle,
+ color: Colors.white,
+ );
+
+ final pointDescriptionStyle = TextStyle(
+ height: 0.1,
+ fontWeight: FontWeight.w700,
+ fontFamily: FontFamily.roboto,
+ fontSize: 9,
+ color: Colors.white,
+ );
+
return _ListItem(
- child: Column(
- children: [
- Expanded(
- child: Align(
- alignment: Alignment.centerLeft,
- child: Padding(
- padding: EdgeInsets.all(4.0),
- child: Text(searchResult.name!, style: textStyle,)
- )
- )
- ),
- Align(
- alignment: Alignment.bottomCenter,
- child: ClipRRect(
- borderRadius: BorderRadius.only(
- bottomLeft: Radius.circular(5),
- bottomRight: Radius.circular(5)
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Container(
+ width: leftBoxSize,
+ height: leftBoxSize,
+ decoration: BoxDecoration(
+ color: AppColors.defaultRed,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(leftBoxSize / 2),
+ bottomLeft: Radius.circular(leftBoxSize / 2),
+ ),
+ ),
+ alignment: Alignment.center,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ '${searchResult.companies?.first.plScore ?? 0}',
+ style: pointValueStyle,
+ textAlign: TextAlign.center,
+ ),
+ Text(
+ t.scan.pkt,
+ style: pointDescriptionStyle,
+ textAlign: TextAlign.center,
+ ),
+ ],
),
- child: LinearProgressIndicator(
- value:(searchResult.companies?.first.plScore ?? 0) / 100.toDouble(),
- backgroundColor: Colors.white,
- semanticsLabel: 'Linear progress indicator',
+ ),
+ SizedBox(width: 8.0),
+ Expanded(
+ child: Container(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ searchResult.name!,
+ style: TextStyle(
+ fontWeight: FontWeight.w400,
+ fontSize: TextSize.smallTitle,
+ ),
+ overflow: TextOverflow.ellipsis,
+ maxLines: 1,
+ ),
),
),
- )],
- )
+ ],
+ ),
);
}
}
@@ -46,49 +87,71 @@ class LoadingListItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final textStyle = TextStyle(fontWeight: FontWeight.normal, fontSize: TextSize.mediumTitle);
return _ListItem(
- child: Expanded(
- child: Align(
- alignment: Alignment.centerLeft,
- child: Padding(
- padding: EdgeInsets.all(4.0),
- child: Row(
- children: [
+ child: Align(
+ alignment: Alignment.centerLeft,
+ child: Padding(
+ padding: EdgeInsets.all(4.0),
+ child: Row(
+ children: [
CircularProgressIndicator(),
Padding(
- padding: EdgeInsets.only(left: 8.0),
- child: Text("Ładowanie...",style: textStyle,)
- )]
- )
+ padding: EdgeInsets.only(left: 8.0),
+ child: Text(
+ t.scan.wait,
+ style: TextStyle(
+ fontWeight:
+ FontWeight.w400,
+ fontSize:
+ TextSize.smallTitle,
+ ),
+ ),
+ ),
+ ],
),
),
- )
+ ),
+ showMore: false,
);
}
}
class _ListItem extends StatelessWidget {
final Widget child;
+ final bool showMore;
- const _ListItem({required this.child});
+ const _ListItem({
+ required this.child,
+ this.showMore = true,
+ });
@override
Widget build(BuildContext context) {
return Padding(
- padding: EdgeInsets.only(top: 4.0, left: 8.0, right: 8.0, bottom: 4.0),
+ padding: EdgeInsets.only(top: 4.0, left: 16.0, right: 8.0, bottom: 4.0),
child: Container(
- height: 50,
+ height: 40,
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
- topLeft: Radius.circular(5),
- topRight: Radius.circular(5),
- bottomRight: Radius.circular(5),
- bottomLeft: Radius.circular(5)),
+ topLeft: Radius.circular(30),
+ topRight: Radius.circular(30),
+ bottomRight: Radius.circular(30),
+ bottomLeft: Radius.circular(30),
+ ),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(child: child),
+ if (showMore)
+ Padding(
+ padding: EdgeInsets.only(right: 8.0),
+ child: Assets.scan.showMore.svg(),
+ ),
+ ],
),
- child: child,
),
),
);
diff --git a/pubspec.yaml b/pubspec.yaml
index cc66e2e..ab1b19b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -58,6 +58,7 @@ flutter:
- assets/fonts/
- assets/company/
- assets/navigation/
+ - assets/scan/
fonts:
- family: Roboto