Skip to content
Open
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
39 changes: 39 additions & 0 deletions assets/translations/en-US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"enter_team_member_name_add_person_widget": "Enter team member name",
"add_member_add_person_widget": "Add Member",
"cancel_add_member_add_person_widget": "Cancel",
"standup_complete_celebration_screen": "Standup Complete!",
"great_job_celebration_screen": "Great job everyone! 🎉",
"participants_celebration_screen": "Participants ({count})",
"start_new_session_celebration_screen": "Start New Session",
"please_add_participants_current_speaker": "Please add participants",
"team_members_current_speaker": "Team Members",
"person_position_current_speaker": "Person {current} of {total}",
"previous_navigation_controls": "Previous",
"next_navigation_controls": "Next",
"finish_navigation_controls": "Finish",
"english_people_section": "English",
"portuguese_people_section": "Portuguese",
"team_members_people_section": "Team Members",
"clear_all_people_section": "Clear all",
"shuffle_order_people_section": "Shuffle order",
"team_options_people_section": "Team options",
"no_team_members_added_people_section": "No team members added",
"click_to_add_or_paste_people_section": "Click + to add members or paste a participant list",
"session_info": "Session Info",
"total_members_session_info": "Total members:",
"expected_duration_session_info": "Expected duration:",
"time_per_person_session_info": "Time per person:",
"timer_configuration_session_info": "Timer Configuration",
"reset_timer_controls": "Reset",
"start_timer_timer_controls": "Start Timer",
"pause_timer_controls": "Pause",
"error_prefix_comic_screen": "An error occurred while trying to connect to the server.\nPlease check your connection or try again later.",
"failed_to_load_image_comic_screen": "Failed to load image",
"no_data_available_comic_screen": "No data available",
"added_participants_timer_page": "Added {count} new {entity}",
"participant_timer_page": "participant",
"participants_timer_page": "participants",
"no_new_participants_timer_page": "No new participants added (duplicates were skipped)",
"failed_paste_timer_page": "Failed to paste from clipboard"
}
39 changes: 39 additions & 0 deletions assets/translations/pt-PT.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"enter_team_member_name_add_person_widget": "Introduza o nome do membro da equipa",
"add_member_add_person_widget": "Adicionar Membro",
"cancel_add_member_add_person_widget": "Cancelar",
"standup_complete_celebration_screen": "Standup Concluído!",
"great_job_celebration_screen": "Bom trabalho a todos! 🎉",
"participants_celebration_screen": "Participantes ({count})",
"start_new_session_celebration_screen": "Iniciar Nova Sessão",
"please_add_participants_current_speaker": "Por favor adicione participantes",
"team_members_current_speaker": "Membros da Equipa",
"person_position_current_speaker": "Pessoa {current} de {total}",
"previous_navigation_controls": "Anterior",
"next_navigation_controls": "Próximo",
"finish_navigation_controls": "Concluir",
"english_people_section": "Inglês",
"portuguese_people_section": "Português",
"team_members_people_section": "Membros da Equipa",
"clear_all_people_section": "Limpar tudo",
"shuffle_order_people_section": "Embaralhar ordem",
"team_options_people_section": "Opções da equipa",
"no_team_members_added_people_section": "Nenhum membro adicionado",
"click_to_add_or_paste_people_section": "Clique + para adicionar membros ou cole uma lista de participantes",
"session_info": "Informação da Sessão",
"total_members_session_info": "Total de membros:",
"expected_duration_session_info": "Duração esperada:",
"time_per_person_session_info": "Tempo por pessoa:",
"timer_configuration_session_info": "Configuração do Temporizador",
"reset_timer_controls": "Reiniciar",
"start_timer_timer_controls": "Iniciar Temporizador",
"pause_timer_controls": "Pausar",
"error_prefix_comic_screen": "Ocorreu um erro ao tentar ligar ao servidor. \nVerifique a sua ligação ou tente novamente mais tarde.",
"failed_to_load_image_comic_screen": "Falha ao carregar imagem",
"no_data_available_comic_screen": "Sem dados disponíveis",
"added_participants_timer_page": "Adicionado(s) {count} novo(s) {entity}",
"participant_timer_page": "participante",
"participants_timer_page": "participantes",
"no_new_participants_timer_page": "Nenhum novo participante adicionado (duplicados foram ignorados)",
"failed_paste_timer_page": "Falha ao colar da área de transferência"
}
46 changes: 33 additions & 13 deletions lib/comic.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:math';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'widgets/timer_controls.dart';
Expand All @@ -22,7 +23,9 @@ class Comic {

Future<Comic> fetchComic() async {
final weekday = DateTime.now().weekday; // Monday=1, Tuesday=2, etc.
if (weekday == DateTime.monday || weekday == DateTime.wednesday || weekday == DateTime.friday) {
if (weekday == DateTime.monday ||
weekday == DateTime.wednesday ||
weekday == DateTime.friday) {
// Fetch the latest XKCD comic on Monday, Wednesday, or Friday.
final response = await http.get(Uri.parse("https://xkcd.com/info.0.json"));
if (response.statusCode == 200) {
Expand All @@ -33,13 +36,15 @@ Future<Comic> fetchComic() async {
} else {
// Otherwise, fetch a random safe-for-work XKCD comic.
// First, get the latest comic to know the maximum comic number.
final latestResponse = await http.get(Uri.parse("https://xkcd.com/info.0.json"));
final latestResponse =
await http.get(Uri.parse("https://xkcd.com/info.0.json"));
if (latestResponse.statusCode == 200) {
final latestJson = json.decode(latestResponse.body);
final maxNum = latestJson['num'];
// Generate a random comic number between 1 and maxNum.
final randomComicNum = Random().nextInt(maxNum) + 1;
final randomResponse = await http.get(Uri.parse("https://xkcd.com/$randomComicNum/info.0.json"));
final randomResponse = await http
.get(Uri.parse("https://xkcd.com/$randomComicNum/info.0.json"));
if (randomResponse.statusCode == 200) {
return Comic.fromJson(json.decode(randomResponse.body));
} else {
Expand Down Expand Up @@ -75,7 +80,11 @@ class ComicScreen extends StatelessWidget {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
return Center(
child: Text(
'error_prefix_comic_screen'.tr(),
textAlign: TextAlign.center,
));
} else if (snapshot.hasData) {
final comic = snapshot.data!;
return LayoutBuilder(
Expand All @@ -85,27 +94,35 @@ class ComicScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.all(16),
child: Text(
comic.title,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
comic.title,
style: const TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
Expanded(
child: Container(
width: constraints.maxWidth,
height: constraints.maxHeight - (showTimerControls ? 180 : 120), // Reserve space for controls if needed
height: constraints.maxHeight -
(showTimerControls
? 180
: 120), // Reserve space for controls if needed
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Image.network(
comic.img,
fit: BoxFit.contain,
width: constraints.maxWidth - 32,
height: constraints.maxHeight - (showTimerControls ? 180 : 120),
height: constraints.maxHeight -
(showTimerControls ? 180 : 120),
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return const Center(child: CircularProgressIndicator());
return const Center(
child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Center(child: Text('Failed to load image'));
return Center(
child: Text(
'failed_to_load_image_comic_screen'.tr()));
},
),
),
Expand All @@ -115,7 +132,8 @@ class ComicScreen extends StatelessWidget {
padding: const EdgeInsets.all(16),
child: Text(
comic.alt,
style: const TextStyle(fontSize: 14, fontStyle: FontStyle.italic),
style: const TextStyle(
fontSize: 14, fontStyle: FontStyle.italic),
textAlign: TextAlign.center,
),
),
Expand All @@ -135,9 +153,11 @@ class ComicScreen extends StatelessWidget {
},
);
} else {
return const Center(child: Text('No data available'));
return Center(
child: Text('no_data_available_comic_screen').tr(),
);
}
},
);
}
}
}
Loading