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

Mobile styling #25

Merged
merged 5 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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 frontend-mobile/assets/coffee_cup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend-mobile/lib/communication/coffee_caller_protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class CoffeeCallerProtocol {

final SocketClient _socketClient;

void connect() {
_socketClient.init();
}

void join(String username) {
_send(CoffeeCallerMessageType.join, username);
}
Expand Down
16 changes: 8 additions & 8 deletions frontend-mobile/lib/communication/socket_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'dart:async';

import 'package:socket_io_client/socket_io_client.dart' as socket_io;

enum SocketClientConnectStatus { disconnected, connecting, connected, error }
enum SocketConnectStatus { unknown, disconnected, connecting, connected, error }

class SocketClient {
Stream<SocketClientConnectStatus> get connectStatusStream =>
Stream<SocketConnectStatus> get connectStatusStream =>
_statusController.stream;

Stream<String> get coffeeMessageStream => _coffeeMessageController.stream;
Expand All @@ -17,25 +17,25 @@ class SocketClient {
});

final socket_io.Socket _socket;
final _statusController = StreamController<SocketClientConnectStatus>();
final _statusController = StreamController<SocketConnectStatus>();
final _coffeeMessageController = StreamController<String>();

void init() {
_statusController.sink.add(SocketClientConnectStatus.connecting);
_statusController.sink.add(SocketConnectStatus.connecting);
_socket.connect();

_socket.onConnect((_) {
_statusController.sink.add(SocketClientConnectStatus.connected);
_statusController.sink.add(SocketConnectStatus.connected);
});
_socket.onDisconnect(
(_) => _statusController.sink.add(SocketClientConnectStatus.disconnected),
(_) => _statusController.sink.add(SocketConnectStatus.disconnected),
);

_socket.onConnectError(
(err) => _statusController.sink.add(SocketClientConnectStatus.error),
(err) => _statusController.sink.add(SocketConnectStatus.error),
);
_socket.onError(
(err) => _statusController.sink.add(SocketClientConnectStatus.error),
(err) => _statusController.sink.add(SocketConnectStatus.error),
);

_socket.on('coffee', (data) => _coffeeMessageController.sink.add(data));
Expand Down
30 changes: 24 additions & 6 deletions frontend-mobile/lib/screens/settings_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,32 @@ class _SettingsScreenState extends State<SettingsScreen> {
margin: const EdgeInsets.fromLTRB(4, 12, 4, 4),
child: Column(
children: [
TextField(
controller: _usernameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username',
Hero(
tag: 'coffee-cup',
child: Image.asset(
'assets/coffee_cup.png',
width: 50,
height: 50,
),
),
Padding(
padding: const EdgeInsets.all(10),
child: TextField(
controller: _usernameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username',
),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(),
onPressed: _save,
child: const Text(
'Save',
style: TextStyle(fontSize: 16),
),
),
TextButton(onPressed: _save, child: const Text('Save'))
],
),
),
Expand Down
35 changes: 20 additions & 15 deletions frontend-mobile/lib/widgets/coffee_call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,33 @@ class _CoffeeCallBodyState extends State<CoffeeCallBody> {
});
}

void _onCoffeeCupClicked() {
context.read<CoffeeCallCubit>().next();
}

@override
Widget build(BuildContext context) {
if (userName == '') {
return NoUsername(onUsernameSet: _setUsername);
}
return Column(
children: [
Row(
children: [
TextButton(
onPressed: context.read<CoffeeCallCubit>().join,
child: const Text('Join'),
),
TextButton(
onPressed: context.read<CoffeeCallCubit>().leave,
child: const Text('Leave'),
Padding(
padding: const EdgeInsets.all(20),
child: Hero(
tag: 'coffee-cup',
child: Material(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the Material here? My gut feeling tells me, this should be handled by the MaterialApp in main.dart

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jep, your right! Thats just Copy Pasta

child: ElevatedButton(
onPressed: _onCoffeeCupClicked,
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(48),
),
child: Image.asset('assets/coffee_cup.png',
height: 200, width: 200),
),
),
TextButton(
onPressed: context.read<CoffeeCallCubit>().start,
child: const Text('Start'),
),
],
),
),
BlocBuilder<CoffeeCallCubit, CoffeeCallState>(
builder: (context, state) {
Expand All @@ -87,7 +92,7 @@ class _CoffeeCallBodyState extends State<CoffeeCallBody> {
shrinkWrap: true,
);
},
)
),
],
);
}
Expand Down
58 changes: 33 additions & 25 deletions frontend-mobile/lib/widgets/cubit/coffee_call_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:coffee_caller/communication/coffee_caller_protocol.dart';
import 'package:coffee_caller/communication/models/coffee_caller_message.dart';
import 'package:coffee_caller/communication/socket_client.dart';
import 'package:coffee_caller/storage/settings_storage.dart';
import 'package:coffee_caller/widgets/cubit/coffee_call_state.dart';
import 'package:coffee_caller/communication/socket_client.dart';

class CoffeeCallCubit extends Cubit<CoffeeCallState> {
SocketClient socket;
CoffeeCallerProtocol protocol;

late StreamSubscription connectionStatusSubscription;
late StreamSubscription coffeeMessageSubscription;

CoffeeCallCubit({
required this.socket,
required this.protocol,
}) : super(const CoffeeCallState());

void init() {
socket.connectStatusStream.listen((status) {
switch (status) {
case SocketClientConnectStatus.disconnected:
emit(state.copyWith(status: CoffeeCallStatus.disconnected));
break;
case SocketClientConnectStatus.connected:
emit(state.copyWith(status: CoffeeCallStatus.connected));
break;
case SocketClientConnectStatus.error:
emit(state.copyWith(status: CoffeeCallStatus.disconnected));
break;
case SocketClientConnectStatus.connecting:
// do nothing
break;
}
emit(state.copyWith(connectStatus: status));
});

protocol.messages.listen((message) {
Expand All @@ -43,26 +26,51 @@ class CoffeeCallCubit extends Cubit<CoffeeCallState> {
final second = localDate.second.toString().padLeft(2, '0');
final time = '$hour:$minute:$second';

emit(state.copyWith(messages: [
var newStatus = _getNextStatusByMessageType(message.type);

emit(state.copyWith(status: newStatus, messages: [
...state.messages,
'${message.name} ${message.type.name}s a coffee call @$time',
]));
});
}

void next() {
if (state.status == CoffeeCallStatus.unknown) {
_join();
return;
}
if (state.status == CoffeeCallStatus.initiated) {
_start();
return;
}
_leave();
}

void connect() {
socket.init();
protocol.connect();
}

void join() async {
void _join() async {
protocol.join(await getUsername());
}

void start() async {
void _start() async {
protocol.start(await getUsername());
}

void leave() async {
void _leave() async {
protocol.leave(await getUsername());
}

CoffeeCallStatus _getNextStatusByMessageType(
CoffeeCallerMessageType messageType) {
if (messageType == CoffeeCallerMessageType.join) {
return CoffeeCallStatus.initiated;
}
if (messageType == CoffeeCallerMessageType.start) {
return CoffeeCallStatus.started;
}
return CoffeeCallStatus.unknown;
}
}
6 changes: 4 additions & 2 deletions frontend-mobile/lib/widgets/cubit/coffee_call_state.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'package:coffee_caller/communication/socket_client.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'coffee_call_state.freezed.dart';

enum CoffeeCallStatus { initial, connected, disconnected }
enum CoffeeCallStatus { unknown, initiated, started, canceled }

@freezed
class CoffeeCallState with _$CoffeeCallState {
const factory CoffeeCallState([
@Default(CoffeeCallStatus.initial) CoffeeCallStatus status,
@Default(CoffeeCallStatus.unknown) CoffeeCallStatus status,
@Default(SocketConnectStatus.unknown) SocketConnectStatus connectStatus,
@Default([]) List<String> messages,
]) = _CoffeeCallState;
}
35 changes: 31 additions & 4 deletions frontend-mobile/lib/widgets/cubit/coffee_call_state.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ final _privateConstructorUsedError = UnsupportedError(
/// @nodoc
mixin _$CoffeeCallState {
CoffeeCallStatus get status => throw _privateConstructorUsedError;
SocketConnectStatus get connectStatus => throw _privateConstructorUsedError;
List<String> get messages => throw _privateConstructorUsedError;

@JsonKey(ignore: true)
Expand All @@ -29,7 +30,10 @@ abstract class $CoffeeCallStateCopyWith<$Res> {
factory $CoffeeCallStateCopyWith(
CoffeeCallState value, $Res Function(CoffeeCallState) then) =
_$CoffeeCallStateCopyWithImpl<$Res>;
$Res call({CoffeeCallStatus status, List<String> messages});
$Res call(
{CoffeeCallStatus status,
SocketConnectStatus connectStatus,
List<String> messages});
}

/// @nodoc
Expand All @@ -44,13 +48,18 @@ class _$CoffeeCallStateCopyWithImpl<$Res>
@override
$Res call({
Object? status = freezed,
Object? connectStatus = freezed,
Object? messages = freezed,
}) {
return _then(_value.copyWith(
status: status == freezed
? _value.status
: status // ignore: cast_nullable_to_non_nullable
as CoffeeCallStatus,
connectStatus: connectStatus == freezed
? _value.connectStatus
: connectStatus // ignore: cast_nullable_to_non_nullable
as SocketConnectStatus,
messages: messages == freezed
? _value.messages
: messages // ignore: cast_nullable_to_non_nullable
Expand All @@ -66,7 +75,10 @@ abstract class _$$_CoffeeCallStateCopyWith<$Res>
_$_CoffeeCallState value, $Res Function(_$_CoffeeCallState) then) =
__$$_CoffeeCallStateCopyWithImpl<$Res>;
@override
$Res call({CoffeeCallStatus status, List<String> messages});
$Res call(
{CoffeeCallStatus status,
SocketConnectStatus connectStatus,
List<String> messages});
}

/// @nodoc
Expand All @@ -83,13 +95,18 @@ class __$$_CoffeeCallStateCopyWithImpl<$Res>
@override
$Res call({
Object? status = freezed,
Object? connectStatus = freezed,
Object? messages = freezed,
}) {
return _then(_$_CoffeeCallState(
status == freezed
? _value.status
: status // ignore: cast_nullable_to_non_nullable
as CoffeeCallStatus,
connectStatus == freezed
? _value.connectStatus
: connectStatus // ignore: cast_nullable_to_non_nullable
as SocketConnectStatus,
messages == freezed
? _value._messages
: messages // ignore: cast_nullable_to_non_nullable
Expand All @@ -102,13 +119,17 @@ class __$$_CoffeeCallStateCopyWithImpl<$Res>

class _$_CoffeeCallState implements _CoffeeCallState {
const _$_CoffeeCallState(
[this.status = CoffeeCallStatus.initial,
[this.status = CoffeeCallStatus.unknown,
this.connectStatus = SocketConnectStatus.unknown,
final List<String> messages = const []])
: _messages = messages;

@override
@JsonKey()
final CoffeeCallStatus status;
@override
@JsonKey()
final SocketConnectStatus connectStatus;
final List<String> _messages;
@override
@JsonKey()
Expand All @@ -119,7 +140,7 @@ class _$_CoffeeCallState implements _CoffeeCallState {

@override
String toString() {
return 'CoffeeCallState(status: $status, messages: $messages)';
return 'CoffeeCallState(status: $status, connectStatus: $connectStatus, messages: $messages)';
}

@override
Expand All @@ -128,13 +149,16 @@ class _$_CoffeeCallState implements _CoffeeCallState {
(other.runtimeType == runtimeType &&
other is _$_CoffeeCallState &&
const DeepCollectionEquality().equals(other.status, status) &&
const DeepCollectionEquality()
.equals(other.connectStatus, connectStatus) &&
const DeepCollectionEquality().equals(other._messages, _messages));
}

@override
int get hashCode => Object.hash(
runtimeType,
const DeepCollectionEquality().hash(status),
const DeepCollectionEquality().hash(connectStatus),
const DeepCollectionEquality().hash(_messages));

@JsonKey(ignore: true)
Expand All @@ -146,11 +170,14 @@ class _$_CoffeeCallState implements _CoffeeCallState {
abstract class _CoffeeCallState implements CoffeeCallState {
const factory _CoffeeCallState(
[final CoffeeCallStatus status,
final SocketConnectStatus connectStatus,
final List<String> messages]) = _$_CoffeeCallState;

@override
CoffeeCallStatus get status;
@override
SocketConnectStatus get connectStatus;
@override
List<String> get messages;
@override
@JsonKey(ignore: true)
Expand Down
Loading