Skip to content

Commit

Permalink
feat: add firebase analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
Ziedelth committed Sep 7, 2024
1 parent e842b0b commit 2a86823
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 91 deletions.
3 changes: 1 addition & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
id "com.google.gms.google-services"
}

def localProperties = new Properties()
Expand Down Expand Up @@ -78,5 +79,3 @@ android {
flutter {
source '../..'
}

dependencies {}
1 change: 1 addition & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.5.0" apply false
id "org.jetbrains.kotlin.android" version "2.0.10" apply false
id "com.google.gms.google-services" version '4.4.0' apply false
}

include ":app"
3 changes: 3 additions & 0 deletions lib/components/animes/anime_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:application/components/image_component.dart';
import 'package:application/components/lang_type_component.dart';
import 'package:application/controllers/anime_controller.dart';
import 'package:application/dtos/anime_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/utils/constant.dart';
import 'package:application/views/anime_details_view.dart';
import 'package:flutter/material.dart';
Expand All @@ -20,6 +21,8 @@ class AnimeComponent extends StatelessWidget {
Widget build(BuildContext context) {
return CustomCard(
onTap: () {
Analytics.instance.logSelectContent('anime', anime.uuid);

Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AnimeDetailsView(anime: anime),
Expand Down
3 changes: 3 additions & 0 deletions lib/components/animes/calendar_anime_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:application/components/lang_type_component.dart';
import 'package:application/components/platforms/list_platform.dart';
import 'package:application/controllers/anime_controller.dart';
import 'package:application/dtos/week_day_release_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/views/anime_details_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
Expand Down Expand Up @@ -40,6 +41,8 @@ class _CalendarAnimeComponentState extends State<CalendarAnimeComponent> {
activateLayers: widget.release.isMultipleReleased && _layerColor != null,
layerColor: _layerColor,
onTap: () {
Analytics.instance.logSelectContent('anime', widget.release.anime.uuid);

Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AnimeDetailsView(anime: widget.release.anime),
Expand Down
9 changes: 6 additions & 3 deletions lib/components/animes/missed_anime_component.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'package:application/components/card_component.dart';
import 'package:application/components/image_component.dart';
import 'package:application/components/pill.dart';
import 'package:application/controllers/missed_anime_controller.dart';
import 'package:application/controllers/anime_controller.dart';
import 'package:application/dtos/missed_anime_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/views/anime_details_view.dart';
import 'package:flutter/material.dart';

Expand All @@ -19,15 +20,17 @@ class MissedAnimeComponent extends StatelessWidget {
return CustomCard(
backgroundColor: Colors.transparent,
onTap: () {
Analytics.instance.logSelectContent('anime', missedAnime.anime.uuid);

Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AnimeDetailsView(anime: missedAnime.anime),
),
);
},
onLongPress: (details) {
MissedAnimeController.instance
.onLongPress(context, missedAnime, details);
AnimeController.instance
.onLongPress(context, missedAnime.anime, details);
},
child: SizedBox(
width: 100,
Expand Down
3 changes: 3 additions & 0 deletions lib/controllers/anime_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:application/controllers/member_controller.dart';
import 'package:application/controllers/missed_anime_controller.dart';
import 'package:application/controllers/simulcast_controller.dart';
import 'package:application/dtos/anime_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/utils/constant.dart';
import 'package:application/utils/http_request.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -114,6 +115,8 @@ class AnimeController {
.then((value) => MissedAnimeController.instance.init());
Vibration.vibrate(pattern: [0, 50, 125, 50, 125, 50]);
} else if (value == 1) {
Analytics.instance.logShare('anime', anime.uuid, 'onLongPress');

Share.share(
'${Constant.baseUrl}/animes/${anime.slug}',
);
Expand Down
10 changes: 9 additions & 1 deletion lib/controllers/anime_search_controller.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:application/dtos/anime_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/utils/http_request.dart';
import 'package:flutter/material.dart';

Expand Down Expand Up @@ -62,8 +63,10 @@ class AnimeSearchController {
isLoading = true;

try {
final searchTypesString =
searchTypes.map((e) => e.name.toUpperCase()).join(',');
final pageableDto = await HttpRequest.instance.getPage(
'/v1/animes?country=FR&name=${Uri.encodeComponent(query)}&page=$page&limit=6&searchTypes=${searchTypes.map((e) => e.name.toUpperCase()).join(',')}');
'/v1/animes?country=FR&name=${Uri.encodeComponent(query)}&page=$page&limit=6&searchTypes=$searchTypesString');

animes.addAll(
pageableDto.data
Expand All @@ -72,6 +75,11 @@ class AnimeSearchController {

streamController.add(animes);
canLoadMore = animes.length < pageableDto.total;

Analytics.instance.logSearch(query, {
'page': page,
'searchTypes': searchTypesString,
});
} catch (e) {
debugPrint(e.toString());
} finally {
Expand Down
3 changes: 3 additions & 0 deletions lib/controllers/member_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:typed_data';
import 'package:application/dtos/anime_dto.dart';
import 'package:application/dtos/episode_mapping_dto.dart';
import 'package:application/dtos/member_dto.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/utils/http_request.dart';
import 'package:application/views/crop_view.dart';
import 'package:crop_your_image/crop_your_image.dart';
Expand Down Expand Up @@ -64,6 +65,7 @@ class MemberController {
final String identifier =
jsonDecode(utf8.decode(response.bodyBytes))['identifier'];
await _sharedPreferences.setString('identifier', identifier);
Analytics.instance.logSignUp();
return identifier;
}

Expand Down Expand Up @@ -93,6 +95,7 @@ class MemberController {

member = MemberDto.fromJson(json);
streamController.add(member!);
Analytics.instance.logLogin();
}

Future<void> changeImage(BuildContext context) async {
Expand Down
47 changes: 0 additions & 47 deletions lib/controllers/missed_anime_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@ import 'dart:async';

import 'package:application/controllers/member_controller.dart';
import 'package:application/dtos/missed_anime_dto.dart';
import 'package:application/utils/constant.dart';
import 'package:application/utils/http_request.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:share_plus/share_plus.dart';
import 'package:vibration/vibration.dart';

class MissedAnimeController {
static MissedAnimeController instance = MissedAnimeController();
Expand Down Expand Up @@ -97,47 +93,4 @@ class MissedAnimeController {
page++;
}
}

void onLongPress(
BuildContext context,
MissedAnimeDto missedAnime,
TapDownDetails? details,
) {
if (details == null) {
return;
}

final RenderBox renderBox =
Overlay.of(context).context.findRenderObject() as RenderBox;

// Show dropdown menu
showMenu<int>(
context: context,
position: RelativeRect.fromRect(
details.globalPosition & const Size(40, 40),
Offset.zero & renderBox.size,
),
items: [
PopupMenuItem(
value: 0,
child: Text(AppLocalizations.of(context)!.markWatched),
),
PopupMenuItem(
value: 1,
child: Text(AppLocalizations.of(context)!.share),
),
],
).then((value) {
if (value == 0) {
MemberController.instance
.followAllEpisodes(missedAnime.anime)
.then((value) => refresh());
Vibration.vibrate(pattern: [0, 50, 125, 50, 125, 50]);
} else if (value == 1) {
Share.share(
'${Constant.baseUrl}/animes/${missedAnime.anime.slug}',
);
}
});
}
}
22 changes: 8 additions & 14 deletions lib/controllers/notifications_controller.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'dart:async';

import 'package:application/controllers/member_controller.dart';
import 'package:application/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:shared_preferences/shared_preferences.dart';

Expand All @@ -17,18 +15,14 @@ class NotificationsController {
final String key = 'notificationsType';
late final SharedPreferences _sharedPreferences;
final streamController = StreamController<NotificationsType>.broadcast();
final _messaging = FirebaseMessaging.instance;

NotificationsType get notificationsType =>
NotificationsType.values[_sharedPreferences.getInt(key) ?? 0];

Future<void> init() async {
_sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

final response =
await FirebaseMessaging.instance.requestPermission(provisional: true);
final response = await _messaging.requestPermission(provisional: true);

if (response.authorizationStatus != AuthorizationStatus.authorized) {
return;
Expand All @@ -44,18 +38,18 @@ class NotificationsController {

switch (type) {
case NotificationsType.all:
await FirebaseMessaging.instance.subscribeToTopic('global');
await FirebaseMessaging.instance
await _messaging.subscribeToTopic('global');
await _messaging
.unsubscribeFromTopic(MemberController.instance.member!.uuid);
break;
case NotificationsType.watchlist:
await FirebaseMessaging.instance
await _messaging
.subscribeToTopic(MemberController.instance.member!.uuid);
await FirebaseMessaging.instance.unsubscribeFromTopic('global');
await _messaging.unsubscribeFromTopic('global');
break;
case NotificationsType.none:
await FirebaseMessaging.instance.unsubscribeFromTopic('global');
await FirebaseMessaging.instance
await _messaging.unsubscribeFromTopic('global');
await _messaging
.unsubscribeFromTopic(MemberController.instance.member!.uuid);
break;
}
Expand Down
47 changes: 39 additions & 8 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import 'package:application/controllers/notifications_controller.dart';
import 'package:application/controllers/sort_controller.dart';
import 'package:application/dtos/member_dto.dart';
import 'package:application/dtos/missed_anime_dto.dart';
import 'package:application/firebase_options.dart';
import 'package:application/utils/analytics.dart';
import 'package:application/utils/constant.dart';
import 'package:application/views/account_settings_view.dart';
import 'package:application/views/account_view.dart';
Expand All @@ -19,6 +21,7 @@ import 'package:application/controllers/simulcast_controller.dart';
import 'package:application/views/no_internet.dart';
import 'package:application/views/search_view.dart';
import 'package:application/views/simulcast_view.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand All @@ -33,6 +36,10 @@ Future<void> main() async {
}

try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

await MemberController.instance.init();

await Future.wait([
Expand All @@ -42,7 +49,6 @@ Future<void> main() async {
.init()
.then((value) => AnimeController.instance.init()),
AnimeWeeklyController.instance.init(),
NotificationsController.instance.init(),
SortController.instance.init(),
]);

Expand Down Expand Up @@ -139,6 +145,11 @@ class _MyHomePageState extends State<MyHomePage> {
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);

WidgetsBinding.instance.addPostFrameCallback((_) {
NotificationsController.instance.init();
Analytics.instance.logScreenView('home');
});
}

@override
Expand Down Expand Up @@ -208,9 +219,7 @@ class _MyHomePageState extends State<MyHomePage> {
body: PageView(
controller: pageController,
onPageChanged: (index) {
setState(() {
_currentIndex = index;
});
_changePage(index);
},
children: const [
HomeView(),
Expand Down Expand Up @@ -301,13 +310,35 @@ class _MyHomePageState extends State<MyHomePage> {
}
} else {
pageController.jumpToPage(index);

setState(() {
_currentIndex = index;
});
_changePage(index);
}
},
),
);
}

void _changePage(int index) {
setState(() {
_currentIndex = index;
});

String screenName = '';

switch (index) {
case 0:
screenName = 'home';
break;
case 1:
screenName = 'catalog';
break;
case 2:
screenName = 'calendar';
break;
case 3:
screenName = 'account';
break;
}

Analytics.instance.logScreenView(screenName);
}
}
Loading

0 comments on commit 2a86823

Please sign in to comment.