Skip to content
Merged

Dev #14

Show file tree
Hide file tree
Changes from all commits
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
8 changes: 4 additions & 4 deletions lib/features/events/models/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ part 'event.g.dart';

@JsonSerializable()
class Event {
String id;
String sessionId;
String? id;
String? sessionId;
DateTime createdAt;
String eventName;
String urlPath;
String referrerDomain;

Event({
required this.createdAt,
required this.id,
required this.sessionId,
this.id,
this.sessionId,
required this.eventName,
required this.urlPath,
required this.referrerDomain,
Expand Down
4 changes: 2 additions & 2 deletions lib/features/events/models/event.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 11 additions & 10 deletions lib/features/events/widgets/event_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@ class EventCard extends StatelessWidget {
spacing: 15,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 50,
height: 50,
child: BoringAvatar(
name: event.sessionId,
type: BoringAvatarType.beam,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
if (event.sessionId != null)
SizedBox(
width: 50,
height: 50,
child: BoringAvatar(
name: event.sessionId!,
type: BoringAvatarType.beam,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
),
),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down Expand Up @@ -64,7 +65,7 @@ class EventCard extends StatelessWidget {
),
],
),
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Expand Down
49 changes: 28 additions & 21 deletions lib/features/overview/widgets/metric_card.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:country_codes/country_codes.dart';
import 'package:country_flags/country_flags.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -37,28 +38,34 @@ class MetricCard extends StatelessWidget {
),
),
if (state.metric == 'Country')
Row(
spacing: 10,
children: [
CountryFlag.fromCountryCode(
met.x,
width: 30,
height: 20,
shape: const RoundedRectangle(2),
),
Text(
met.x,
style: kBodyTextStyle.copyWith(
fontWeight: FontWeight.w700,
Expanded(
child: Row(
spacing: 10,
children: [
CountryFlag.fromCountryCode(
met.x,
width: 30,
height: 20,
shape: const RoundedRectangle(2),
),
),
Text(
'(${NumberFormat.compact().format(met.y)})',
style: kBodyTextStyle.copyWith(
fontWeight: FontWeight.w700,
Expanded(
child: Text(
'${CountryCodes.name(locale: Locale('en-GB', met.x))}',
maxLines: 1,
style: kBodyTextStyle.copyWith(
fontWeight: FontWeight.w700,
overflow: TextOverflow.ellipsis,
),
),
),
),
],
Text(
'(${NumberFormat.compact().format(met.y)})',
style: kBodyTextStyle.copyWith(
fontWeight: FontWeight.w700,
),
),
],
),
)
else
Text(
Expand All @@ -67,7 +74,7 @@ class MetricCard extends StatelessWidget {
fontWeight: FontWeight.w700,
),
),
const Spacer(),
if (state.metric != 'Country') const Spacer(),
Text(
'${OverviewRepo().getMetricPercentage(met.y, state.metrics.map((e) => e.y).toList()).toStringAsFixed(1)} %',
style: kBodyTextStyle.copyWith(
Expand Down
14 changes: 11 additions & 3 deletions lib/features/overview/widgets/stat_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:icons_plus/icons_plus.dart';
import 'package:pulse/features/overview/repo/overview_repo.dart';
import 'package:pulse/utils/text.dart';
import 'package:intl/intl.dart';
import 'package:pulse/utils/utils.dart';
import '../../../utils/colors.dart';
import '../../../widgets/container_wrapper.dart';

Expand All @@ -25,9 +26,16 @@ class StatCard extends StatelessWidget {
children: [
Text(stat.key.toUpperCase(),
style: kBodyTitleTextStyle.copyWith(color: kGreyColor)),
Text(NumberFormat.compact().format((stat.value as Map)['value']),
style: kTitleTextStyle.copyWith(
fontSize: kTitleTextStyle.fontSize! + 8)),
if (stat.key.toLowerCase() == 'totaltime')
FittedBox(
child: Text(formatDuration((stat.value as Map)['value']),
style: kTitleTextStyle.copyWith(
fontSize: kTitleTextStyle.fontSize! + 8)),
)
else
Text(NumberFormat.compact().format((stat.value as Map)['value']),
style: kTitleTextStyle.copyWith(
fontSize: kTitleTextStyle.fontSize! + 8)),
if (stat.value['prev'] != -1)
Container(
padding: EdgeInsets.symmetric(horizontal: 14.0, vertical: 4),
Expand Down
18 changes: 18 additions & 0 deletions lib/features/sessions/cubit/sessions_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:pulse/features/events/models/event.dart';
import 'package:pulse/features/sessions/model/session.dart';
import 'package:pulse/features/sessions/repo/sessions_repo.dart';

Expand Down Expand Up @@ -34,4 +35,21 @@ class SessionsCubit extends Cubit<SessionsState> {
state.copyWith(appState: AppState.error, errorMessage: e.toString()));
}
}

Future<void> getSessionEvents({
required String websiteId,
required String id,
DateTime? start,
DateTime? end,
}) async {
emit(state.copyWith(appState: AppState.loading, events: []));
try {
var res = await SessionsRepo().getSessionEvents(
id: id, start: start, end: end, websiteId: websiteId);
emit(state.copyWith(appState: AppState.complete, events: res));
} catch (e) {
emit(
state.copyWith(appState: AppState.error, errorMessage: e.toString()));
}
}
}
6 changes: 5 additions & 1 deletion lib/features/sessions/cubit/sessions_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@ part of 'sessions_cubit.dart';
class SessionsState extends Equatable {
final AppState appState;
final List<Session> sessions;
final List<Event> events;
final String? errorMessage;
const SessionsState({
this.appState = AppState.initial,
this.errorMessage,
this.sessions = const [],
this.events = const [],
});

@override
List<Object?> get props => [appState, errorMessage, sessions];
List<Object?> get props => [appState, errorMessage, sessions, events];

SessionsState copyWith({
AppState? appState,
String? errorMessage,
List<Session>? sessions,
List<Event>? events,
}) {
return SessionsState(
appState: appState ?? this.appState,
errorMessage: errorMessage ?? this.errorMessage,
sessions: sessions ?? this.sessions,
events: events ?? this.events,
);
}
}
19 changes: 19 additions & 0 deletions lib/features/sessions/repo/sessions_repo.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:pulse/features/events/models/event.dart';
import 'package:pulse/features/sessions/model/session.dart';
import 'package:pulse/utils/endpoints.dart';
import 'package:pulse/utils/requests.dart';
Expand Down Expand Up @@ -30,4 +31,22 @@ class SessionsRepo {

return Session.fromJson(res);
}

Future<List<Event>> getSessionEvents({
required String websiteId,
required String id,
DateTime? start,
DateTime? end,
}) async {
var now = DateTime.now();
int startAt = (start ?? now.subtract(const Duration(hours: 24)))
.millisecondsSinceEpoch;
int endAt = (end ?? now).millisecondsSinceEpoch;
var res = await Requests.get(
useKey: true,
endpoint:
'${Endpoints.websites.replaceAll(Endpoints.baseUrl, 'https://api.umami.is/v1')}/$websiteId/sessions/$id/activity?startAt=$startAt&endAt=$endAt');
logger.i(res);
return Event.toList(res);
}
}
Loading
Loading