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

feat: add settings to Flutter App #88

Merged
merged 60 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
577c563
feat: get current session information
sashatalalasha Aug 18, 2023
6b5239c
feat: create login flow
sashatalalasha Aug 18, 2023
8ec2806
feat: login with email and password
sashatalalasha Aug 23, 2023
b89a99d
feat: register with email and password
sashatalalasha Aug 23, 2023
81290a0
fix: handle all errors incl deserialization error
sashatalalasha Aug 24, 2023
e00383d
feat: logout & get session on home page init
sashatalalasha Aug 24, 2023
a6459a0
feat: show session information
sashatalalasha Aug 29, 2023
bd77e99
feat: add design and refactor blocs
sashatalalasha Sep 1, 2023
e7658a3
fix: change package and folder name
sashatalalasha Sep 1, 2023
e033adf
fix: change package name
sashatalalasha Sep 1, 2023
f297235
docs: update README.md
sashatalalasha Sep 1, 2023
7244c6c
refactor: delete unused icon
sashatalalasha Sep 1, 2023
6f7ddc6
refactor: remove unused packages
sashatalalasha Sep 1, 2023
b43fdd0
chore: format code
sashatalalasha Sep 1, 2023
3cf26b0
refactor: add missing package and delete unused test
sashatalalasha Sep 4, 2023
2f30a6f
feat: change password in settings
sashatalalasha Sep 6, 2023
12307ba
design: add padding to messages
sashatalalasha Sep 6, 2023
0e9fac8
feat: refresh session when updating settings
sashatalalasha Sep 6, 2023
1ce89da
design: add assets' variants
sashatalalasha Sep 8, 2023
e6eb441
feat: display settings dynamically
sashatalalasha Sep 18, 2023
9d17c9d
chore: create widgets
sashatalalasha Sep 20, 2023
5598f8c
fix: chnge submit button value
sashatalalasha Sep 22, 2023
bd1e90f
chore: format code
sashatalalasha Sep 22, 2023
e631a1f
chore: display components dynamically
sashatalalasha Oct 2, 2023
6917e92
chore: clean up and format code
sashatalalasha Oct 2, 2023
8f771f0
fix: aal2 navigation
sashatalalasha Oct 2, 2023
9cd1bd1
Merge branch 'flutter-app-email-password' into flutter-app-change-pas…
sashatalalasha Oct 2, 2023
c9de1f1
chore: remove unnecessary code
sashatalalasha Oct 4, 2023
b815ba1
feat: sign in/up with google account on iOS
sashatalalasha Oct 11, 2023
1cfd74e
chore: add ios url scheme and web clientId
sashatalalasha Oct 11, 2023
1203c21
chore: fix typo and rename variables
sashatalalasha Oct 16, 2023
ce12100
chore: separate exception handlings
sashatalalasha Oct 16, 2023
3719abd
fix: prevent null exception
sashatalalasha Oct 16, 2023
a8a95bb
Merge branch 'flutter-app-email-password' into flutter-app-social-sig…
sashatalalasha Oct 18, 2023
9718f4e
Merge branch 'flutter-app-email-password' into flutter-app-change-pas…
sashatalalasha Oct 18, 2023
78bc88e
chore: delete unused assets & widgets
sashatalalasha Oct 18, 2023
84afc46
fix: remove pop & show provider buttons correctly
sashatalalasha Oct 18, 2023
8e3b2ec
chore: separate exception handlings
sashatalalasha Oct 18, 2023
3d10cc0
chore: format code
sashatalalasha Oct 18, 2023
7439b5c
chore: change package name and add auth packages
sashatalalasha Oct 20, 2023
7a21e5c
feat: add apple & google sign in
sashatalalasha Oct 23, 2023
cf68bc1
chore: delete unnecessary exception handling
sashatalalasha Oct 23, 2023
e64fc40
feat: add flutter app Ory Network example (#82)
sashatalalasha Oct 18, 2023
e21fed5
Merge branch 'master' into flutter-app-social-sign-in
sashatalalasha Oct 25, 2023
a595f29
chore: delete unused assets and widgets
sashatalalasha Oct 25, 2023
3d83120
chore: remove misleading widget
sashatalalasha Oct 25, 2023
8a03f41
Update README.md
sashatalalasha Oct 25, 2023
f1a78c6
Update README.md
sashatalalasha Oct 25, 2023
a08df3d
chore: add formatting
sashatalalasha Oct 25, 2023
d58aa9c
chore: add formatting
sashatalalasha Oct 25, 2023
c8bd923
Merge branch 'master' into flutter-app-change-password
sashatalalasha Oct 25, 2023
ee82b48
Merge branch 'flutter-app-social-sign-in' into flutter-app-change-pas…
sashatalalasha Oct 26, 2023
978e3df
chore: regenerate freezed files
sashatalalasha Oct 26, 2023
8a6c06c
fix: rebuild settings page or reset buttons
sashatalalasha Oct 30, 2023
74cf3ac
chore: refactor auth state & add missing social login functionality
sashatalalasha Nov 3, 2023
1500ee4
Merge branch 'master' into flutter-app-change-password
sashatalalasha Nov 27, 2023
76c49d3
chore: use helpers to get nodes of group
sashatalalasha Nov 27, 2023
a779d50
fix: reset settings when navigating back
sashatalalasha Nov 29, 2023
f78cfe6
chore: delete build artifacts
sashatalalasha Dec 1, 2023
26a0d3b
fix: typo
sashatalalasha Dec 13, 2023
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
Binary file added .DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.ory.flutter_ory_network

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added flutter-ory-network/assets/icons/1.5x/eye-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/1.5x/eye.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/1.5x/logout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/1.5x/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/2.0x/eye-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/2.0x/eye.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/2.0x/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/3.0x/eye-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/3.0x/eye.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/3.0x/logout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/4.0x/eye-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/4.0x/eye.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/4.0x/logout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/logout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/icons/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/1.5x/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/1.5x/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/2.0x/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/2.0x/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/3.0x/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/3.0x/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/4.0x/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flutter-ory-network/assets/images/apple.png
Binary file added flutter-ory-network/assets/images/google.png
7 changes: 4 additions & 3 deletions flutter-ory-network/lib/blocs/auth/auth_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ part of 'auth_bloc.dart';
@immutable
sealed class AuthEvent extends Equatable {
@override
List<Object> get props => [];
List<Object?> get props => [];
jonas-jonas marked this conversation as resolved.
Show resolved Hide resolved
}

final class ChangeAuthStatus extends AuthEvent {
final AuthStatus status;
final Session? session;

ChangeAuthStatus({required this.status});
ChangeAuthStatus({required this.status, this.session});
@override
List<Object> get props => [status];
List<Object?> get props => [status, session];
}

final class GetCurrentSessionInformation extends AuthEvent {}
Expand Down
10 changes: 5 additions & 5 deletions flutter-ory-network/lib/blocs/auth/auth_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ part of 'auth_bloc.dart';
@freezed
sealed class AuthState with _$AuthState {
const factory AuthState.uninitialized(
{@Default(AuthStatus.uninitialized) AuthStatus status,
{@Default(AuthStatus.uninitialized) final AuthStatus status,
@Default(false) bool isLoading,
String? errorMessage}) = AuthUninitialized;
const factory AuthState.unauthenticated(
{@Default(AuthStatus.unauthenticated) AuthStatus status,
{@Default(AuthStatus.unauthenticated) final AuthStatus status,
@Default(false) bool isLoading,
String? errorMessage}) = AuthUnauthenticated;
const factory AuthState.authenticated(
{@Default(AuthStatus.authenticated) AuthStatus status,
{@Default(AuthStatus.authenticated) final AuthStatus status,
required Session session,
@Default(false) bool isLoading,
String? errorMessage}) = AuthAuthenticated;

const factory AuthState.aal2Requested(
{@Default(AuthStatus.aal2Requested) AuthStatus status,
{@Default(AuthStatus.aal2Requested) final AuthStatus status,
@Default(false) bool isLoading,
String? errorMessage}) = Aal2Requested;

const factory AuthState.locationChangeRequired(
{@Default(AuthStatus.locationChangeRequired) AuthStatus status,
{@Default(AuthStatus.locationChangeRequired) final AuthStatus status,
required String url,
@Default(false) bool isLoading,
String? errorMessage}) = LocationChangeRequired;
Expand Down
6 changes: 3 additions & 3 deletions flutter-ory-network/lib/blocs/login/login_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
CreateLoginFlow event, Emitter<LoginState> emit) async {
try {
emit(state.copyWith(isLoading: true, message: null));

final loginFlow = await repository.createLoginFlow(aal: event.aal);

final loginFlow = await repository.createLoginFlow(
aal: event.aal, refresh: event.refresh);
emit(state.copyWith(loginFlow: loginFlow, isLoading: false));
} on UnknownException catch (e) {
emit(state.copyWith(isLoading: false, message: e.message));
Expand Down Expand Up @@ -102,6 +101,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
value: event.value,
nodes: state.loginFlow!.ui.nodes.toList());
authBloc.add(AddSession(session: session));
emit(state.copyWith(isLoading: false));
} on BadRequestException<LoginFlow> catch (e) {
emit(state.copyWith(loginFlow: e.flow, isLoading: false));
} on LocationChangeRequiredException catch (e) {
Expand Down
5 changes: 3 additions & 2 deletions flutter-ory-network/lib/blocs/login/login_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ sealed class LoginEvent extends Equatable {

final class CreateLoginFlow extends LoginEvent {
final String aal;
final bool refresh;

CreateLoginFlow({required this.aal});
CreateLoginFlow({this.refresh = false, required this.aal});
@override
List<Object> get props => [aal];
List<Object> get props => [refresh, aal];
}

class ChangeNodeValue extends LoginEvent {
Expand Down
128 changes: 128 additions & 0 deletions flutter-ory-network/lib/blocs/settings/settings_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:equatable/equatable.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:ory_client/ory_client.dart';
import 'package:ory_network_flutter/repositories/auth.dart';

import '../../repositories/settings.dart';
import '../../services/exceptions.dart';
import '../auth/auth_bloc.dart';

part 'settings_event.dart';
part 'settings_state.dart';

part 'settings_bloc.freezed.dart';

class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
final AuthBloc authBloc;
final SettingsRepository repository;
late SettingsEvent? _previousEvent;
SettingsBloc({required this.authBloc, required this.repository})
: super(const SettingsState()) {
on<CreateSettingsFlow>(_onCreateSettingsFlow);
on<GetSettingsFlow>(_onGetSettingsFlow);
on<ChangeSettingsNodeValue>(_onChangeNodeValue, transformer: sequential());
on<ResetSettings>(_onResetSettings);
on<UpdateSettingsFlow>(_onUpdateSettingsFlow, transformer: sequential());
}

@override
void onEvent(SettingsEvent event) {
super.onEvent(event);
_previousEvent = event;
}

void retry() {
if (_previousEvent != null) {
add(_previousEvent!);
}
}

_onChangeNodeValue(
ChangeSettingsNodeValue event, Emitter<SettingsState> emit) {
if (state.settingsFlow != null) {
final newSettingsState = repository.changeNodeValue(
settings: state.settingsFlow!, name: event.name, value: event.value);
emit(state.copyWith(settingsFlow: newSettingsState, message: null));
}
}

_onResetSettings(ResetSettings event, Emitter<SettingsState> emit) async {
if (state.settingsFlow != null) {
emit(state.copyWith(isLoading: true));
final settings =
await repository.getSettingsFlow(flowId: state.settingsFlow!.id);
emit(state.copyWith(
settingsFlow: settings,
isSessionRefreshRequired: false,
isLoading: false));
}
}

Future<void> _onUpdateSettingsFlow(
UpdateSettingsFlow event, Emitter<SettingsState> emit) async {
try {
if (state.settingsFlow != null) {
emit(state.copyWith(
isLoading: true, isSessionRefreshRequired: false, message: null));
final settings = await repository.updateSettingsFlow(
flowId: state.settingsFlow!.id,
group: event.group,
nodes: state.settingsFlow!.ui.nodes.toList());
emit(state.copyWith(isLoading: false, settingsFlow: settings));
}
} on UnauthorizedException catch (_) {
// change auth status as the user is not authenticated
authBloc.add(ChangeAuthStatus(status: AuthStatus.unauthenticated));
} on FlowExpiredException catch (e) {
// get new settings flow
add(GetSettingsFlow(flowId: e.flowId));
} on SessionRefreshRequiredException catch (_) {
// set session refresh required flag to navigate to login page
emit(state.copyWith(isSessionRefreshRequired: true, isLoading: false));
} on UnknownException catch (e) {
emit(state.copyWith(isLoading: false, message: e.message));
} catch (_) {
emit(state.copyWith(isLoading: false));
}
}

Future<void> _onCreateSettingsFlow(
SettingsEvent event, Emitter<SettingsState> emit) async {
try {
emit(state.copyWith(isLoading: true, message: null));

final settingsFlow = await repository.createSettingsFlow();

emit(state.copyWith(isLoading: false, settingsFlow: settingsFlow));
} on UnauthorizedException catch (_) {
// change auth status as the user is not authenticated
authBloc.add(ChangeAuthStatus(status: AuthStatus.unauthenticated));
} on UnknownException catch (e) {
emit(state.copyWith(isLoading: false, message: e.message));
} catch (_) {
emit(state.copyWith(isLoading: false));
}
}

Future<void> _onGetSettingsFlow(
GetSettingsFlow event, Emitter<SettingsState> emit) async {
try {
emit(state.copyWith(isLoading: true));
final settingsFlow =
await repository.getSettingsFlow(flowId: event.flowId);
emit(state.copyWith(isLoading: false, settingsFlow: settingsFlow));
} on UnauthorizedException catch (_) {
// change auth status as the user is not authenticated
authBloc.add(ChangeAuthStatus(status: AuthStatus.unauthenticated));
} on UnknownException catch (e) {
emit(state.copyWith(isLoading: false, message: e.message));
} catch (_) {
emit(state.copyWith(isLoading: false));
}
}
}
Loading
Loading