Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sharezone Wrapped #1660

Merged
merged 27 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e0fe40a
Add `SharezoneRewrappedView`
nilsreichardt Jun 9, 2024
34d551d
Add tests for `SharezoneRewrappedView`
nilsreichardt Jun 9, 2024
012630d
Add `SharezoneRewrappedRepository`
nilsreichardt Jun 9, 2024
a1912a3
Add `SharezoneRewrappedController`
nilsreichardt Jun 9, 2024
77a358f
Add first UI and rename to wrapped
nilsreichardt Jun 9, 2024
8d31cff
Merge remote-tracking branch 'origin/main' into sharezone-rewrapped
nilsreichardt Jun 13, 2024
4c960f6
Rename test rewrapped to wrapped
nilsreichardt Jun 21, 2024
a7ebd8e
Add equality operator to `AnalyticsEvent`
nilsreichardt Jun 21, 2024
6827f2d
Add tests for `SharezoneWrappedController`
nilsreichardt Jun 21, 2024
a7281ff
Fix typo in analytics event
nilsreichardt Jun 21, 2024
488311b
Merge remote-tracking branch 'origin/main' into sharezone-rewrapped
nilsreichardt Jun 21, 2024
e29374a
Update mocks
nilsreichardt Jun 21, 2024
f27d857
Add screenshot package
nilsreichardt Jun 21, 2024
79b69e7
Add graduation cap
nilsreichardt Jun 21, 2024
846ebd8
Update Podfile.lock
nilsreichardt Jun 21, 2024
bda7ae3
Add tip for wrapped
nilsreichardt Jun 21, 2024
8762131
Mostly complete the wrapped feature
nilsreichardt Jun 21, 2024
79a222d
Add remote config
nilsreichardt Jun 21, 2024
856b860
Fix unit test
nilsreichardt Jun 21, 2024
a398c07
Fix unused stuff
nilsreichardt Jun 21, 2024
985256f
Add lh
nilsreichardt Jun 21, 2024
8681cfb
Refactor
nilsreichardt Jun 21, 2024
c4c9ad3
Fix shared
nilsreichardt Jun 23, 2024
14f00cd
Update settings page test
nilsreichardt Jun 23, 2024
63c716b
Merge remote-tracking branch 'origin/main' into sharezone-rewrapped
nilsreichardt Jun 23, 2024
7f4bf32
Fix analyzer
nilsreichardt Jun 23, 2024
6bf5919
Add FAQ and fix for iPad
nilsreichardt Jun 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/assets/icons/graduation-cap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion app/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ SPEC CHECKSUMS:
GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd
image_picker_ios: b545a5f16c0fa88e3ecbbce3ed4de45567a8ec18
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
integration_test: 13825b8a9334a850581300559b8839134b124670
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
Expand Down
2 changes: 1 addition & 1 deletion app/lib/dashboard/sections/dashboard_tip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class _DashboardTipCard extends StatelessWidget {
child: Text(dashboardTip.action.title.toUpperCase()),
onPressed: () {
dashboardTip.markAsShown();
dashboardTip.action.onTap();
dashboardTip.action.onTap(context);
},
),
],
Expand Down
7 changes: 6 additions & 1 deletion app/lib/dashboard/tips/dashboard_tip_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:bloc_base/bloc_base.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sharezone/dashboard/tips/cache/dashboard_tip_cache.dart';
import 'package:sharezone/dashboard/tips/models/rate_our_app_tip.dart';
import 'package:sharezone/dashboard/tips/models/wrapped_tip.dart';
import 'package:sharezone/navigation/logic/navigation_bloc.dart';
import 'package:sharezone/settings/src/bloc/user_tips_bloc.dart';

Expand All @@ -36,12 +37,16 @@ class DashboardTipSystem extends BlocBase {
UserTipsBloc userTipsBloc,
) {
final rateOurAppTip = RateOurAppTip(cache);
final wrappedTip =
SharezoneWrappedTip(cache, userTipsBloc.streamAccountCreatedOn());

final tips = [rateOurAppTip];
final tips = [rateOurAppTip, wrappedTip];

return CombineLatestStream(tips.map((tip) => tip.shouldShown()).toList(),
(streamValues) {
final showRateOurAppCard = streamValues[0];
final showWrappedTip = streamValues[1];
if (showWrappedTip) return wrappedTip;
if (showRateOurAppCard) return rateOurAppTip;
return null;
});
Expand Down
4 changes: 2 additions & 2 deletions app/lib/dashboard/tips/models/action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Action {
final String title;
final VoidCallback onTap;
final void Function(BuildContext context) onTap;

const Action({
required this.title,
Expand Down
2 changes: 1 addition & 1 deletion app/lib/dashboard/tips/models/rate_our_app_tip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RateOurAppTip implements DashboardTip {

@override
Action get action =>
Action(title: "App bewerten", onTap: () => launchURL(_getStoreLink()));
Action(title: "App bewerten", onTap: (_) => launchURL(_getStoreLink()));

String _getStoreLink() {
const sharezoneLink = 'https://sharezone.net';
Expand Down
57 changes: 57 additions & 0 deletions app/lib/dashboard/tips/models/wrapped_tip.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) 2022 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:flutter/material.dart' hide Action;
import 'package:rxdart/rxdart.dart';
import 'package:sharezone/dashboard/tips/cache/dashboard_tip_cache.dart';
import 'package:sharezone/dashboard/tips/models/action.dart';
import 'package:sharezone/dashboard/tips/models/dashboard_tip.dart';
import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart';

class SharezoneWrappedTip implements DashboardTip {
static const _showedDashboardRatingCardKey =
"dashboard-showed-wrapped-23-24-tip";

final DashboardTipCache cache;
final Stream<DateTime?> accountCreatedOn;

SharezoneWrappedTip(this.cache, this.accountCreatedOn);

@override
Action get action => Action(
title: "Ansehen",
onTap: (context) =>
Navigator.pushNamed(context, SharezoneWrappedPage.tag));

@override
String get text =>
"Das Schuljahr ist vorbei! Sieh dir dein Sharezone Wrapped 23/24 an 🎉";

@override
String get title => "Sharezone Wrapped 23/24";

@override
Stream<bool> shouldShown() {
return CombineLatestStream([
cache.showedTip(_showedDashboardRatingCardKey),
accountCreatedOn,
], (streamValues) {
final showedDashboardCounterCard = streamValues[0] as bool? ?? false;
final createdOn = streamValues[1] as DateTime?;

// New user shouldn't see the Sharezone Wrapped tip because their Wrapped
// will be mostly empty.
final isOldUser = createdOn?.isBefore(DateTime(2024, 5, 1)) == true;

return !showedDashboardCounterCard && isOldUser;
});
}

@override
void markAsShown() => cache.markTipAsShown(_showedDashboardRatingCardKey);
}
3 changes: 2 additions & 1 deletion app/lib/main/plugin_initializations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class PluginInitializations {
'firebase_messaging_vapid_key':
'BNT7Da6B6wi-mUBcGrt-9HxeIJZsPTsPpmR8cae_LhgJPcSFb5j0T8o-r-oFV1xAtXVXfRPIZlgUJR3tx8mLbbA',
'stripe_checkout_session_function_url':
'https://europe-west1-sharezone-c2bd8.cloudfunctions.net/createStripeCheckoutSession'
'https://europe-west1-sharezone-c2bd8.cloudfunctions.net/createStripeCheckoutSession',
'show_sz_wrapped_23_24': true,
});

try {
Expand Down
3 changes: 3 additions & 0 deletions app/lib/main/sharezone_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import 'package:sharezone/settings/src/subpages/notification.dart';
import 'package:sharezone/settings/src/subpages/theme/theme_page.dart';
import 'package:sharezone/settings/src/subpages/timetable/timetable_settings_page.dart';
import 'package:sharezone/settings/src/subpages/web_app.dart';
import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart';
import 'package:sharezone/sharezone_v2/sz_v2_announcement_dialog.dart';
import 'package:sharezone/support/support_page.dart';
import 'package:sharezone/timetable/timetable_add/timetable_add_page.dart';
Expand Down Expand Up @@ -207,6 +208,8 @@ class _SharezoneAppState extends State<SharezoneApp>
ICalLinksDialog.tag: (context) => const ICalLinksDialog(),
CreateTermPage.tag: (context) => const CreateTermPage(),
GradesDialog.tag: (context) => const GradesDialog(),
SharezoneWrappedPage.tag: (context) =>
const SharezoneWrappedPage(),
},
navigatorKey: navigationService.navigatorKey,
),
Expand Down
20 changes: 19 additions & 1 deletion app/lib/main/sharezone_bloc_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import 'package:http/http.dart' as http;
import 'package:key_value_store/in_memory_key_value_store.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:remote_configuration/remote_configuration.dart';
import 'package:sharezone/account/account_page_bloc_factory.dart';
import 'package:sharezone/account/change_data_bloc.dart';
import 'package:sharezone/account/type_of_user_bloc.dart';
Expand Down Expand Up @@ -116,6 +117,8 @@ import 'package:sharezone/sharezone_plus/page/sharezone_plus_page_controller.dar
import 'package:sharezone/sharezone_plus/subscription_service/is_buying_enabled.dart';
import 'package:sharezone/sharezone_plus/subscription_service/revenue_cat_sharezone_plus_service.dart';
import 'package:sharezone/sharezone_plus/subscription_service/subscription_service.dart';
import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_controller.dart';
import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_repository.dart';
import 'package:sharezone/support/support_page_controller.dart';
import 'package:sharezone/timetable/src/bloc/timetable_bloc.dart';
import 'package:sharezone/timetable/src/models/lesson_length/lesson_length_cache.dart';
Expand Down Expand Up @@ -355,6 +358,9 @@ class _SharezoneBlocProvidersState extends State<SharezoneBlocProviders> {
create: (context) => api.user.authUserStream,
initialData: null,
),
Provider<RemoteConfiguration>(
create: (context) => widget.blocDependencies.remoteConfiguration,
),
ChangeNotifierProvider(
create: (context) => SharezonePlusPageController(
buyingFlagApi: BuyingEnabledApi(client: http.Client()),
Expand Down Expand Up @@ -484,7 +490,19 @@ class _SharezoneBlocProvidersState extends State<SharezoneBlocProviders> {
courseMemberAccessor:
FirestoreCourseMemberAccessor(api.references.firestore),
),
)
),
Provider(
create: (context) => SharezoneWrappedController(
repository: SharezoneWrappedRepository(
firestore: firestore,
userId: api.userId,
connectionsGateway: api.connectionsGateway,
clock: clock,
),
crashAnalytics: crashAnalytics,
analytics: analytics,
),
),
];

mainBlocProviders = <BlocProvider>[
Expand Down
28 changes: 22 additions & 6 deletions app/lib/settings/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import 'package:analytics/analytics.dart';
import 'package:bloc_provider/bloc_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
import 'package:remote_configuration/remote_configuration.dart';
import 'package:sharezone/legal/terms_of_service/terms_of_service_page.dart';
import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/navigation/logic/navigation_bloc.dart';
Expand All @@ -19,11 +21,13 @@ import 'package:sharezone/settings/src/subpages/changelog_page.dart';
import 'package:sharezone/settings/src/subpages/notification.dart';
import 'package:sharezone/settings/src/subpages/about/about_page.dart';
import 'package:sharezone/settings/src/subpages/theme/theme_page.dart';
import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart';
import 'package:sharezone/support/support_page.dart';
import 'package:sharezone/settings/src/subpages/timetable/timetable_settings_page.dart';
import 'package:sharezone/settings/src/subpages/web_app.dart';
import 'package:sharezone/legal/privacy_policy/privacy_policy_page.dart';
import 'package:platform_check/platform_check.dart';
import 'package:sharezone/widgets/limited_chip.dart';
import 'package:sharezone_utils/launch_link.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';

Expand Down Expand Up @@ -145,29 +149,38 @@ class _LegalSection extends StatelessWidget {
class _AppSettingsSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const _SettingsSection(
final remoteConfig = context.read<RemoteConfiguration>();
final showWrapped = remoteConfig.getBool('show_sz_wrapped_23_24');
return _SettingsSection(
title: 'App-Einstellungen',
children: <Widget>[
_SettingsOption(
const _SettingsOption(
title: "Mein Konto",
icon: Icon(Icons.account_circle),
tag: MyProfilePage.tag,
),
_SettingsOption(
const _SettingsOption(
title: "Benachrichtigungen",
icon: Icon(Icons.notifications_active),
tag: NotificationPage.tag,
),
_SettingsOption(
const _SettingsOption(
title: "Erscheinungsbild",
icon: Icon(Icons.color_lens),
tag: ThemePage.tag,
),
_SettingsOption(
const _SettingsOption(
title: "Stundenplan",
icon: Icon(Icons.access_time),
tag: TimetableSettingsPage.tag,
)
),
if (showWrapped)
const _SettingsOption(
title: "Schuljahr 23/24 Sharezone Wrapped",
icon: Icon(Icons.fast_rewind),
tag: SharezoneWrappedPage.tag,
trailing: LimitedChip(),
)
],
);
}
Expand Down Expand Up @@ -249,11 +262,13 @@ class _SettingsOption extends StatelessWidget {
this.icon,
this.onTap,
this.tag,
this.trailing,
});

final String? title;
final Widget? icon;
final GestureTapCallback? onTap;
final Widget? trailing;
final String? tag;

@override
Expand All @@ -262,6 +277,7 @@ class _SettingsOption extends StatelessWidget {
title: Text(title!),
leading: icon,
onTap: onTap ?? () => Navigator.pushNamed(context, tag!),
trailing: trailing,
);
}
}
4 changes: 4 additions & 0 deletions app/lib/settings/src/bloc/user_tips_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class UserTipsBloc extends BlocBase {
return _userGateway.userStream.map((user) => user?.userTipData);
}

Stream<DateTime?> streamAccountCreatedOn() {
return _userGateway.userStream.map((user) => user?.createdOn);
}

void enableUserTip(UserTipKey tipKey) {
_updateUserTip(tipKey, true);
}
Expand Down
Loading
Loading