Skip to content

Commit

Permalink
delete my account (apache#25255)
Browse files Browse the repository at this point in the history
  • Loading branch information
darkhan.nausharipov committed Feb 6, 2023
1 parent a34b170 commit eda0bfe
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 64 deletions.
4 changes: 3 additions & 1 deletion learning/tour-of-beam/frontend/assets/translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ ui:
continueGoogle: Continue with Google
copyright: © The Apache Software Foundation
hint: Hint
deleteAccount: Delete my account
deleteMyAccount: Delete my account
deleteTobAccount: Delete my Tour of Beam account
privacyPolicy: Privacy Policy
reportIssue: Report Issue in GitHub
signIn: Sign in
Expand All @@ -47,6 +48,7 @@ pages:

dialogs:
signInIf: If you would like to save your progress and track completed modules
deleteAccountWarning: Are you sure you want to delete your Tour of Beam account? This will permanently erase your learning progress.

complexity:
basic: Basic level
Expand Down
11 changes: 10 additions & 1 deletion learning/tour-of-beam/frontend/lib/auth/notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:flutter/material.dart';

import '../repositories/client/client.dart';

class AuthNotifier extends ChangeNotifier {
AuthNotifier() {
final TobClient client;

AuthNotifier({required this.client}) {
FirebaseAuth.instance.authStateChanges().listen((user) {
notifyListeners();
});
Expand All @@ -42,4 +46,9 @@ class AuthNotifier extends ChangeNotifier {
Future<void> logOut() async {
await FirebaseAuth.instance.signOut();
}

Future<void> deleteAccount() async {
await client.postDeleteUserProgress();
await FirebaseAuth.instance.currentUser?.delete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,29 @@ class _Buttons extends StatelessWidget {
),
const BeamDivider(),
_IconLabel(
onTap: () {},
onTap: () {
closeOverlayCallback();
showDialog(
context: context,
builder: (context) => Dialog(
backgroundColor: Colors.transparent,
child: BeamAlertDialog(
continueLabel: 'ui.deleteMyAccount'.tr(),
title: 'ui.deleteTobAccount'.tr(),
body: 'dialogs.deleteAccountWarning'.tr(),
onContinue: () {
authNotifier.deleteAccount().then(
(_) {
Navigator.pop(context);
},
);
},
),
),
);
},
iconPath: Assets.svg.profileDelete,
label: 'ui.deleteAccount'.tr(),
label: 'ui.deleteMyAccount'.tr(),
),
],
);
Expand Down
1 change: 0 additions & 1 deletion learning/tour-of-beam/frontend/lib/constants/sizes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
class TobSizes {
static const double footerHeight = 35;
static const double authOverlayWidth = 260;
static const double hintPopupWidth = 420;
}

class ScreenSizes {
Expand Down
16 changes: 8 additions & 8 deletions learning/tour-of-beam/frontend/lib/locator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,24 @@ import 'router/page_factory.dart';
import 'router/route_information_parser.dart';
import 'state.dart';

final _client = CloudFunctionsTobClient();

Future<void> initializeServiceLocator() async {
_initializeAuth();
_initializeState();
_initializeCaches();
}

void _initializeAuth() {
GetIt.instance.registerSingleton(AuthNotifier());
GetIt.instance.registerSingleton(AuthNotifier(client: _client));
}

void _initializeCaches() {
final client = CloudFunctionsTobClient();

GetIt.instance.registerSingleton<TobClient>(client);
GetIt.instance.registerSingleton(ContentTreeCache(client: client));
GetIt.instance.registerSingleton(SdkCache(client: client));
GetIt.instance.registerSingleton(UnitContentCache(client: client));
GetIt.instance.registerSingleton(UnitProgressCache(client: client));
GetIt.instance.registerSingleton<TobClient>(_client);
GetIt.instance.registerSingleton(ContentTreeCache(client: _client));
GetIt.instance.registerSingleton(SdkCache(client: _client));
GetIt.instance.registerSingleton(UnitContentCache(client: _client));
GetIt.instance.registerSingleton(UnitProgressCache(client: _client));
}

void _initializeState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class _Popup extends StatelessWidget {
Widget build(BuildContext context) {
return OverlayBody(
child: Container(
width: TobSizes.hintPopupWidth,
width: BeamSizes.popupWidth,
padding: const EdgeInsets.all(BeamSizes.size16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import 'package:flutter_svg/svg.dart';
import 'package:playground_components/playground_components.dart';

import '../../../assets/assets.gen.dart';
import '../../../constants/sizes.dart';
import '../state.dart';

class SolutionButton extends StatelessWidget {
Expand All @@ -49,7 +48,14 @@ class SolutionButton extends StatelessWidget {
context: context,
builder: (context) => Dialog(
backgroundColor: Colors.transparent,
child: _Popup(tourNotifier: tourNotifier),
child: BeamAlertDialog(
continueLabel: 'pages.tour.showSolution'.tr(),
title: 'pages.tour.solveYourself'.tr(),
onContinue: () {
tourNotifier.toggleShowingSolution();
Navigator.pop(context);
},
),
),
);
},
Expand All @@ -63,51 +69,3 @@ class SolutionButton extends StatelessWidget {
);
}
}

class _Popup extends StatelessWidget {
final TourNotifier tourNotifier;

const _Popup({
required this.tourNotifier,
});

@override
Widget build(BuildContext context) {
return OverlayBody(
child: Container(
width: TobSizes.hintPopupWidth,
padding: const EdgeInsets.all(BeamSizes.size16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'pages.tour.solveYourself',
style: Theme.of(context).textTheme.headlineMedium,
).tr(),
const SizedBox(height: BeamSizes.size8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('ui.cancel').tr(),
),
const SizedBox(width: BeamSizes.size8),
TextButton(
onPressed: () {
tourNotifier.toggleShowingSolution();
Navigator.pop(context);
},
child: const Text('pages.tour.showSolution').tr(),
),
],
),
],
),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ abstract class TobClient {
Future<GetUserProgressResponse?> getUserProgress(String sdkId);

Future<void> postUnitComplete(String sdkId, String id);

Future<void> postDeleteUserProgress();
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,17 @@ class CloudFunctionsTobClient extends TobClient {
},
);
}

@override
Future<void> postDeleteUserProgress() async {
final token = await GetIt.instance.get<AuthNotifier>().getToken();
await http.post(
Uri.parse(
'$cloudFunctionsBaseUrl/postDeleteProgress',
),
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token',
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export 'src/util/string.dart';
export 'src/widgets/bubble.dart';
export 'src/widgets/clickable.dart';
export 'src/widgets/complexity.dart';
export 'src/widgets/dialogs/alert_dialog.dart';
export 'src/widgets/divider.dart';
export 'src/widgets/header_icon_button.dart';
export 'src/widgets/loading_error.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class BeamSizes {
static const double loadingIndicator = 40;
static const double splitViewSeparator = BeamSizes.size8;
static const double tabBarHeight = 50;
static const double popupWidth = 420;
}

class BeamBorderRadius {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import 'package:flutter/material.dart';

import '../../../playground_components.dart';

class BeamAlertDialog extends StatelessWidget {
final String? body;
final String continueLabel;
final VoidCallback onContinue;
final String title;

const BeamAlertDialog({
this.body,
required this.continueLabel,
required this.onContinue,
required this.title,
});

@override
Widget build(BuildContext context) {
return OverlayBody(
child: Container(
width: BeamSizes.popupWidth,
padding: const EdgeInsets.all(BeamSizes.size16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: Theme.of(context).textTheme.headlineMedium,
),
if (body != null)
Padding(
padding: const EdgeInsets.only(top: BeamSizes.size8),
child: Text(body!),
),
const SizedBox(height: BeamSizes.size8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
// TODO(nausharipov): review: translate in PGC?
child: const Text('Cancel'),
),
const SizedBox(width: BeamSizes.size8),
TextButton(
onPressed: onContinue,
child: Text(continueLabel),
),
],
),
],
),
),
);
}
}

0 comments on commit eda0bfe

Please sign in to comment.