refactor: Global plausible / signin / log

release/mobdr-v0.0.1
Frédérik Benoist 2023-06-10 18:01:01 +02:00
parent cf394811d2
commit 58b836b90b
19 changed files with 406 additions and 252 deletions

View File

@ -4,19 +4,20 @@ import 'dart:convert';
/// Plausible class. Use the constructor to set the parameters.
class PlausibleTracker {
/// The url of your plausible server e.g. https://plausible.io
String serverUrl;
String userAgent;
String domain;
String screenWidth;
String xForwardedFor;
bool enabled = true;
bool enabled = false;
/// Constructor
PlausibleTracker(this.serverUrl, this.domain,
{this.userAgent = "",
this.screenWidth = "",
this.xForwardedFor = "127.0.0.1"});
PlausibleTracker(
{required this.serverUrl,
required this.domain,
required this.userAgent,
required this.screenWidth,
required this.xForwardedFor});
/// Post event to plausible
Future<int> event(
@ -75,6 +76,8 @@ class PlausibleTracker {
/// check if plausible is UP
Future<bool> hello() async {
this.enabled = false;
try {
final client = HttpClient();
final request = await client.getUrl(Uri.parse(serverUrl + '/api/health'));
@ -88,7 +91,7 @@ class PlausibleTracker {
final postgresStatus = json['postgres'];
final sitesCacheStatus = json['sites_cache'];
return clickhouseStatus == 'ok' &&
this.enabled = clickhouseStatus == 'ok' &&
postgresStatus == 'ok' &&
sitesCacheStatus == 'ok';
}
@ -98,6 +101,6 @@ class PlausibleTracker {
}
}
return false;
return this.enabled;
}
}

View File

@ -16,6 +16,7 @@ import 'package:mobdr/cubit/language/initial_language.dart';
import 'package:mobdr/service/shared_prefs.dart';
import 'package:mobdr/ui/splash_screen.dart';
import 'package:mobdr/service/device_info.dart';
import 'package:mobdr/service/package_info.dart';
import 'package:mobdr/service/directories.dart';
import 'package:mobdr/service/plausible.dart';
@ -55,11 +56,18 @@ Future<void> main() async {
// get/set device informations
await device_info_plus().initPlatformState();
// get/set device informations
await package_info_plus().initPackageInfo();
// set device screenWidth/height
SharedPrefs().screenWidth = window.physicalSize.width;
SharedPrefs().screenHeight = window.physicalSize.height;
// initialize directories
await directories().initDirectories();
/// initialize tracker plausible analytics
await PlausibleUtil.initializePlausible(window.physicalSize.width);
await PlausibleUtil.initializePlausible();
// initialize time zone current device
SharedPrefs().timeZone = getCurrentTimeZone(DateTime.now());
@ -69,14 +77,8 @@ Future<void> main() async {
'https://mp4.ikksgroup.com/MobilePortal4/index.html#ajax/dashboard.html';
// track MobBR
LoggerUtil.dblog('LOG', 'MOBDR', 'Ouverture application', 0);
PlausibleUtil.addEvent(
name: 'access',
page: 'access',
referrer: 'referrerPage',
props: {
'name': SharedPrefs().login,
});
LoggerUtil.dblog(
'LOG', 'MOBDR', 'Démarrage MobDR ' + SharedPrefs().appVersion, 0);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
@ -112,20 +114,8 @@ class MyApp extends StatelessWidget with WidgetsBindingObserver {
} else if (state == AppLifecycleState.resumed) {
LoggerUtil.logNStackInfo("The application is resumed");
if (PlausibleUtil.isPlausibleInitialized()) {
// check if plausible is UP
await PlausibleUtil.hello();
PlausibleUtil.addEvent(
name: 'access',
page: 'access',
referrer: 'referrerPage',
props: {
'name': SharedPrefs().login,
});
} else {
await PlausibleUtil.initializePlausible(window.physicalSize.width);
}
// check if plausible is up and running
await PlausibleUtil.checkPlausibleUp();
} else if (state == AppLifecycleState.inactive) {
LoggerUtil.logNStackInfo("The application is inactive");
} else if (state == AppLifecycleState.detached) {

View File

@ -1,5 +1,4 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';
@ -118,25 +117,23 @@ class ApiProvider {
Future<String> login(
String userName, String pinCode, String securityCode) async {
var body = {
// TODO A REMPLIR
"application": "MobDR ", //+ ExeInfo(exeVersion)
"application": "MobDR " + SharedPrefs().appVersion,
"pin_code": md5.convert(utf8.encode(pinCode)),
"security_code": securityCode, //sCodeSecurite
"langage": "fr",
"screenheight": "0", //SysYRes()
"screenwidth": "0", //SysXRes()
"security_code": securityCode,
"langage": SharedPrefs().langage,
"screenheight": SharedPrefs().screenHeight.truncate().toString(),
"screenwidth": SharedPrefs().screenWidth.truncate().toString(),
"browser_name": "Natif",
"browser_version": "Application",
"engine_name": "Android",
"device_model": "",
"device_type": "mobile", //SysInfoAppareil(sysModele) WDM 23
"device_vendor": "", //SysInfoAppareil(sysFabricant) WDM 23
"browser_version": "Flutter",
"engine_name": SharedPrefs().systemName,
"device_model": SharedPrefs().deviceModel,
"device_type": SharedPrefs().deviceName,
"device_vendor": SharedPrefs().systemName,
"ismobile": 1,
"engine_version": "", // SysVersionAndroid(sysVersionApiLevel)
"os_name": "", // SysVersionAndroid(sysVersionPlateForme)
"os_version": "", //SysVersionAndroid(sysVersionNumÈro)
"fingerprint":
"aa" // TODO: on peut mettre un fingerprint sur la version ou sur l'heure
"engine_version": SharedPrefs().systemName,
"os_name": SharedPrefs().systemName,
"os_version": SharedPrefs().systemVersion,
"fingerprint": SharedPrefs().fingerPrint
};
Response response;
@ -150,8 +147,6 @@ class ApiProvider {
'/guid',
body);
print('res : ' + response.toString());
switch (response.data['autorisation']) {
case 1:

View File

@ -1,14 +1,23 @@
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:mobdr/service/logger_util.dart';
Future<String> getPublicIPAddress() async {
try {
var response =
await http.get(Uri.parse('https://api.ipify.org/?format=json'));
Stopwatch stopwatch = Stopwatch()..start();
var response = await http
.get(Uri.parse('https://api.bigdatacloud.net/data/client-ip'));
stopwatch.stop();
// log tracker
LoggerUtil.dblog(
'LOG', 'MOBDR', 'Get IPAddress', stopwatch.elapsedMilliseconds);
if (response.statusCode == 200) {
var data = json.decode(response.body);
return data['ip'];
return data['ipString'];
}
} catch (e) {
print(e.toString());

View File

@ -1,7 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:mobdr/service/logger_util.dart';
import 'package:mobdr/service/shared_prefs.dart';
@ -19,8 +20,27 @@ class device_info_plus {
if (Platform.isAndroid) {
deviceData =
_readAndroidBuildData(await deviceInfoPlugin.androidInfo);
// device related info
SharedPrefs().systemName = deviceData['brand'];
SharedPrefs().deviceModel = deviceData['model'];
SharedPrefs().deviceName = deviceData['device'];
SharedPrefs().systemVersion = deviceData['version.release'];
SharedPrefs().fingerPrint = md5
.convert(utf8.encode("${deviceData['fingerprint']}"))
.toString();
} else if (Platform.isIOS) {
deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
// device related info
SharedPrefs().systemName = deviceData['systemName'];
SharedPrefs().deviceModel = deviceData['model'];
SharedPrefs().deviceName = deviceData['name'];
SharedPrefs().systemVersion = deviceData['systemVersion'];
SharedPrefs().fingerPrint = md5
.convert(utf8.encode(
"${deviceData['name']}${deviceData['model']}${deviceData['identifierForVendor']}${deviceData['systemVersion']}${deviceData['systemName']}${deviceData['localizedModel']}"))
.toString();
} else if (Platform.isLinux) {
deviceData = _readLinuxDeviceInfo(await deviceInfoPlugin.linuxInfo);
} else if (Platform.isMacOS) {
@ -198,10 +218,11 @@ class device_info_plus {
}
String buildUserAgent(Map<String, dynamic> deviceData) {
String systemName = deviceData['systemName'];
String systemVersion = deviceData['systemVersion'];
String model = deviceData['model'];
return '$systemName $systemVersion; $model';
if (Platform.isAndroid) {
return "${deviceData['brand']} ${deviceData['version.release']}; ${deviceData['model']}";
} else if (Platform.isIOS) {
return "${deviceData['systemName']} ${deviceData['systemVersion']}; ${deviceData['model']}";
} else
return "NO_USER_AGENT";
}
}

View File

@ -0,0 +1,12 @@
import 'package:flutter/foundation.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:mobdr/service/shared_prefs.dart';
class package_info_plus {
Future<void> initPackageInfo() async {
if (!kIsWeb) {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
SharedPrefs().appVersion = packageInfo.version;
}
}
}

View File

@ -5,39 +5,50 @@ import 'package:mobdr/network/get_ip_address.dart';
class PlausibleUtil {
static PlausibleTracker? plausible;
static bool isPlausibleInitialized() {
return plausible != null;
}
static Future<void> initializePlausible() async {
final ipAddress = await getPublicIPAddress();
static Future<void> initializePlausible(double screenWidth) async {
plausible = PlausibleTracker(
"https://plausible.q2ii.fr",
"mobdr.ikksgroup.com",
serverUrl: "https://plausible.q2ii.fr",
domain: "mobdr.ikksgroup.com",
userAgent: SharedPrefs().mobileUserAgent,
screenWidth: SharedPrefs().screenWidth.toString(),
xForwardedFor: ipAddress,
);
await plausible!.hello();
plausible!.userAgent = SharedPrefs().mobileUserAgent;
plausible!.xForwardedFor = await getPublicIPAddress();
plausible!.screenWidth = screenWidth.toString();
plausible!.enabled = await plausible!.hello();
}
static Future<void> hello() async {
plausible!.enabled = await plausible!.hello();
static bool isPlausibleEnabled() {
return plausible?.enabled ?? false;
}
static void addEvent({
static Future<void> checkPlausibleUp() async {
await plausible?.hello();
if (isPlausibleEnabled() && SharedPrefs().login.isNotEmpty) {
// track application access
PlausibleUtil.addEventAsync(
name: 'access',
page: 'access',
referrer: 'referrerPage',
props: {
'name': SharedPrefs().login,
});
}
}
static void addEventAsync({
required String name,
required String page,
String? referrer,
Map<String, String>? props,
}) {
PlausibleUtil.plausible?.event(
}) async {
if (isPlausibleEnabled()) {
plausible?.event(
name: name,
page: page,
referrer: referrer ?? '',
props: props ?? {},
);
}
}
}

View File

@ -177,9 +177,68 @@ class SharedPrefs {
}
/// get/set user time zone
String get timeZone => _sharedPrefs.getString('key_timeZone') ?? "";
String get timeZone => _sharedPrefs.getString('key_timezone') ?? "";
set timeZone(String value) {
_sharedPrefs.setString('key_timeZone', value);
_sharedPrefs.setString('key_timezone', value);
}
/// get/set screenWidth
double get screenWidth => _sharedPrefs.getDouble('key_screenwidth') ?? 0;
set screenWidth(double value) {
_sharedPrefs.setDouble('key_screenwidth', value);
}
/// get/set screenHeight
double get screenHeight => _sharedPrefs.getDouble('key_screenheight') ?? 0;
set screenHeight(double value) {
_sharedPrefs.setDouble('key_screenheight', value);
}
/// get/set appVersion
String get appVersion => _sharedPrefs.getString('key_appversion') ?? "";
set appVersion(String value) {
_sharedPrefs.setString('key_appversion', value);
}
/// get/set fingerPrint
String get fingerPrint =>
_sharedPrefs.getString('key_fingerprint') ??
"b42c213ee55376e501bbf4a7a8607bdc"; //NOFINGERPRINT"
set fingerPrint(String value) {
_sharedPrefs.setString('key_fingerprint', value);
}
/// get/set systemName
String get systemName => _sharedPrefs.getString('key_systemname') ?? "";
set systemName(String value) {
_sharedPrefs.setString('key_systemname', value);
}
/// get/set device_model
String get deviceModel => _sharedPrefs.getString('key_device_model') ?? "";
set deviceModel(String value) {
_sharedPrefs.setString('key_device_model', value);
}
/// get/set device Name
String get deviceName => _sharedPrefs.getString('key_device_name') ?? "";
set deviceName(String value) {
_sharedPrefs.setString('key_device_name', value);
}
/// get/set systemVersion
String get systemVersion =>
_sharedPrefs.getString('key_system_version') ?? "";
set systemVersion(String value) {
_sharedPrefs.setString('key_system_version', value);
}
}

View File

@ -1,9 +1,8 @@
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/service/shared_prefs.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
class AboutPage extends StatefulWidget {
@override
@ -14,20 +13,8 @@ class _AboutPageState extends State<AboutPage> {
// initialize reusable widget
final _reusableWidget = ReusableWidget();
String _version = '1.0.0';
Future<void> _getSystemDevice() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
setState(() {
_version = packageInfo.version;
});
}
@override
void initState() {
if (!kIsWeb) {
_getSystemDevice();
}
super.initState();
}
@ -64,7 +51,7 @@ class _AboutPageState extends State<AboutPage> {
height: 5,
),
Text(
_version,
SharedPrefs().appVersion,
style: TextStyle(fontSize: 14, color: CHARCOAL),
),
],

View File

@ -77,7 +77,7 @@ class _LogPageState extends State<LogPage> {
// track & log page access
final page = 'log';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
}
@override
@ -90,7 +90,7 @@ class _LogPageState extends State<LogPage> {
context: context,
builder: (context) => AlertDialog(
title: Text('Confirmation'),
content: Text('Are you sure you want to delete this log?'),
content: Text('Are you sure you want to delete these logs ?'),
actions: [
TextButton(
child: Text('Cancel'),

View File

@ -28,7 +28,7 @@ class _SettingsPageState extends State<SettingsPage> {
// track & log page access
final page = 'settings';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
setState(() {
_photoQuality = SharedPrefs().photoQuality;
@ -315,6 +315,7 @@ class _SettingsPageState extends State<SettingsPage> {
SharedPrefs().langage = 'fr';
break;
default:
// TODO a vérifier
_language = 'French';
break;
}

View File

@ -5,6 +5,7 @@ import 'package:mobdr/network/api_provider.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/verification.dart';
import 'package:mobdr/service/shared_prefs.dart';
class SigninPage extends StatefulWidget {
@override
@ -37,8 +38,21 @@ class _SigninPageState extends State<SigninPage> {
@override
void initState() {
_etUserName = TextEditingController(text: 'fbenoist');
_etPinCode = TextEditingController(text: '9295');
_etUserName = TextEditingController(text: SharedPrefs().login);
_etPinCode = TextEditingController(text: '');
// clear all user information except login
SharedPrefs().id_utilisateur = 0;
SharedPrefs().email = "";
SharedPrefs().expire = 0;
SharedPrefs().guid = "";
SharedPrefs().langage = "";
SharedPrefs().last_traduction = "";
SharedPrefs().nom = "";
SharedPrefs().prenom = "";
SharedPrefs().version = "";
SharedPrefs().photo = "";
super.initState();
}
@ -106,7 +120,7 @@ class _SigninPageState extends State<SigninPage> {
height: 20,
),
TextField(
keyboardType: TextInputType.emailAddress,
keyboardType: TextInputType.text,
controller: _etUserName,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
@ -116,7 +130,7 @@ class _SigninPageState extends State<SigninPage> {
borderSide:
BorderSide(color: _underlineColor),
),
labelText: 'Email',
labelText: 'User name',
labelStyle:
TextStyle(color: Colors.grey[700])),
),
@ -125,6 +139,7 @@ class _SigninPageState extends State<SigninPage> {
),
TextField(
obscureText: _obscureText,
keyboardType: TextInputType.number,
controller: _etPinCode,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
@ -166,6 +181,7 @@ class _SigninPageState extends State<SigninPage> {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
var apiResponse = await _apiProvider.login(
_etUserName.text, _etPinCode.text, '');
if (apiResponse == 'OK') {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
@ -175,8 +191,10 @@ class _SigninPageState extends State<SigninPage> {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
VerificationPage()));
builder: (_) => VerificationPage(
pp_userName: _etUserName.text,
pp_pinCode:
_etPinCode.text)));
} else {
Fluttertoast.showToast(
msg: apiResponse,

View File

@ -1,16 +1,27 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:mobdr/network/api_provider.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/signin.dart';
class VerificationPage extends StatefulWidget {
final String pp_userName;
final String pp_pinCode;
VerificationPage({required this.pp_userName, required this.pp_pinCode});
@override
_VerificationPageState createState() => _VerificationPageState();
}
class _VerificationPageState extends State<VerificationPage> {
// initialize reusable widget
final _reusableWidget = ReusableWidget();
Color _color1 = Color(0xFF07ac12);
Color _color2 = Color(0xFF515151);
Color _color3 = Color(0xff777777);
@ -33,6 +44,19 @@ class _VerificationPageState extends State<VerificationPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(
color: GlobalStyle.appBarIconThemeColor,
),
elevation: GlobalStyle.appBarElevation,
title: Text(
'Two factor authentification',
style: GlobalStyle.appBarTitle,
),
backgroundColor: GlobalStyle.appBarBackgroundColor,
systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle,
bottom: _reusableWidget.bottomAppBar(),
),
body: ListView(
padding: EdgeInsets.fromLTRB(30, 120, 30, 30),
children: <Widget>[
@ -63,7 +87,7 @@ class _VerificationPageState extends State<VerificationPage> {
child: PinCodeTextField(
autoFocus: true,
appContext: context,
keyboardType: TextInputType.number,
keyboardType: TextInputType.text,
length: 4,
showCursor: false,
obscureText: false,
@ -100,11 +124,13 @@ class _VerificationPageState extends State<VerificationPage> {
width: double.maxFinite,
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
backgroundColor:
MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) =>
_buttonDisabled ? Colors.grey[300]! : _color1,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
overlayColor:
MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
@ -114,14 +140,18 @@ class _VerificationPageState extends State<VerificationPage> {
FocusScope.of(context).unfocus();
var apiResponse = await _apiProvider.login(
'fbenoist', '9295', _securityCode);
widget.pp_userName,
widget.pp_pinCode,
_securityCode);
if (apiResponse == 'OK') {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
MaterialPageRoute(
builder: (context) => HomePage()),
(Route<dynamic> route) => false);
} else {
Fluttertoast.showToast(
msg: apiResponse, toastLength: Toast.LENGTH_SHORT);
msg: apiResponse,
toastLength: Toast.LENGTH_SHORT);
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => SigninPage()),

View File

@ -23,7 +23,7 @@ class _NotificationPageState extends State<NotificationPage> {
// track & log page access
final page = 'notification';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
}
@override

View File

@ -11,6 +11,7 @@ import 'package:mobdr/config/constant.dart';
import 'package:mobdr/events.dart';
import 'package:mobdr/service/plausible.dart';
import 'package:mobdr/service/logger_util.dart';
import 'package:mobdr/service/plausible.dart';
class HomePage extends StatefulWidget {
@override
@ -55,9 +56,18 @@ class _HomePageState extends State<HomePage>
_isSyncing = e.isRunning;
});
// check if plausible is up and running
doAsyncPlausibleCheck().then((_) {
PlausibleUtil.addEventAsync(name: 'pageview', page: 'tab_home');
});
super.initState();
}
Future<void> doAsyncPlausibleCheck() async {
await PlausibleUtil.checkPlausibleUp();
}
void _handleTabSelection() {
/*
setState(() {
@ -161,6 +171,6 @@ class _HomePageState extends State<HomePage>
}
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
}
}

View File

@ -4,11 +4,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobdr/service/shared_prefs.dart';
import 'package:mobdr/service/plausible.dart';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/ui/onboarding.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/signin.dart';
class SplashScreenPage extends StatefulWidget {
@override
@ -28,13 +27,22 @@ class _SplashScreenPageState extends State<SplashScreenPage> {
if (_second == 0) {
_cancelFlashsaleTimer();
if (SharedPrefs().onboarding == 0) {
// if the user has never seen the onboarding page or the user is not logged in
if (SharedPrefs().onboarding == 0 ||
SharedPrefs().id_utilisateur == 0) {
// see !
SharedPrefs().onboarding = 1;
PlausibleUtil.addEvent(name: 'pageview', page: 'onboarding');
// go to OnBoarding page
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => OnBoardingPage()));
// if the user is not logged in
} else if (SharedPrefs().id_utilisateur == 0) {
// go to sign'in page
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => SigninPage()));
} else {
PlausibleUtil.addEvent(name: 'pageview', page: 'tab_home');
// go to home page !
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
}

View File

@ -110,7 +110,7 @@ class _VisitPhotoTypologyPageState extends State<VisitPhotoTypologyPage> {
// track & log page access
final page = 'visit_photo_typology';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
}
@override

View File

@ -65,7 +65,7 @@ class _VisitPhotoTypologyDetailPageState
// track & log page access
final page = 'visit_photo_typology_detail';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
loadData(widget.pp_imageId).then((_) {
setState(() {

View File

@ -72,7 +72,7 @@ class _VisitPhotoTypologyListPageState
// track & log page access
final page = 'visit_photo_typology_list';
LoggerUtil.dblog('LOG', 'MOBDR', 'Page : ${page}', 0);
PlausibleUtil.addEvent(name: 'pageview', page: page);
PlausibleUtil.addEventAsync(name: 'pageview', page: page);
loadData();
}