Skip to content

Commit 17c3343

Browse files
authored
Merge pull request #4 from ngomile/main
Fixes UnitedNationsCareers Source and Adds Long Press Copy to Clipboard
2 parents 2a12c23 + d12d29e commit 17c3343

22 files changed

+311
-277
lines changed

lib/bloc/history_bloc/history_event.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ sealed class HistoryEvent {
77

88
/// [FetchHistory] an event that triggers the bloc to perform the search for jobs
99
/// and return a new state containing the jobs in the history table
10-
class FetchHistory extends HistoryEvent {
10+
final class FetchHistory extends HistoryEvent {
1111
const FetchHistory();
1212
}
1313

1414
/// [ClearHistory] event triggers the deletion of viewed jobs from the history
1515
/// table
16-
class ClearHistory extends HistoryEvent {
16+
final class ClearHistory extends HistoryEvent {
1717
const ClearHistory();
1818
}
1919

2020
/// [AddToHistory] event that triggers an addition of the job into the history database
21-
class AddToHistory extends HistoryEvent {
21+
final class AddToHistory extends HistoryEvent {
2222
const AddToHistory(this.job);
2323

2424
final Job job;

lib/bloc/history_bloc/history_state.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ sealed class HistoryState {
77
}
88

99
/// [HistoryInitial] the initial state of history
10-
class HistoryInitial extends HistoryState {
10+
final class HistoryInitial extends HistoryState {
1111
const HistoryInitial();
1212
}
1313

1414
/// [HistoryLoading] is the state that representst the history list being loaded
15-
class HistoryLoading extends HistoryState {
15+
final class HistoryLoading extends HistoryState {
1616
const HistoryLoading();
1717
}
1818

1919
/// [HistoryLoaded] is the state that represents retrieval of value from history
2020
/// repository
21-
class HistoryLoaded extends HistoryState {
21+
final class HistoryLoaded extends HistoryState {
2222
const HistoryLoaded(this.jobs);
2323

2424
final List<Job> jobs;
@@ -35,7 +35,7 @@ class HistoryLoaded extends HistoryState {
3535
}
3636

3737
/// [HistoryError] is the state of failure from trying to load the history list
38-
class HistoryError extends HistoryState {
38+
final class HistoryError extends HistoryState {
3939
const HistoryError(this.error);
4040

4141
final String error;

lib/bloc/job_description_bloc/job_description_event.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ sealed class JobDescriptionEvent {
44
const JobDescriptionEvent();
55
}
66

7-
class FetchJobDescription extends JobDescriptionEvent {
7+
final class FetchJobDescription extends JobDescriptionEvent {
88
const FetchJobDescription({
99
required this.job,
1010
required this.source,

lib/bloc/theme_bloc/theme_bloc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ part 'theme_event.dart';
88
part 'theme_state.dart';
99

1010
final class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
11-
ThemeBloc(ThemeState themeState) : super(themeState) {
11+
ThemeBloc(super.themeState) {
1212
on<GetThemeEvent>(
1313
(event, emit) async {
1414
final themeSetting = await AppSettings.getTheme();
Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,44 +30,42 @@ class _ToggleThemeButtonsState extends State<ToggleThemeButtons> {
3030
@override
3131
Widget build(BuildContext context) => Column(
3232
children: [
33-
...PreferredTheme.values
34-
.map<Widget>(
35-
(themePref) => RadioListTile(
36-
title: Text(themePref.name),
37-
value: themePref.name,
38-
groupValue: _selectedTheme,
39-
onChanged: (_) {
40-
setState(() {
41-
_selectedTheme = themePref.name;
42-
});
43-
44-
switch (themePref) {
45-
case PreferredTheme.auto:
46-
context.read<ThemeBloc>().add(
47-
const ChangedThemeEvent(
48-
AutoTheme(),
49-
),
50-
);
51-
break;
52-
case PreferredTheme.light:
53-
context.read<ThemeBloc>().add(
54-
const ChangedThemeEvent(
55-
LightTheme(),
56-
),
57-
);
58-
break;
59-
case PreferredTheme.dark:
60-
context.read<ThemeBloc>().add(
61-
const ChangedThemeEvent(
62-
DarkTheme(),
63-
),
64-
);
65-
break;
66-
}
67-
},
68-
),
69-
)
70-
.toList(),
33+
...PreferredTheme.values.map<Widget>(
34+
(themePref) => RadioListTile(
35+
title: Text(themePref.name),
36+
value: themePref.name,
37+
groupValue: _selectedTheme,
38+
onChanged: (_) {
39+
setState(() {
40+
_selectedTheme = themePref.name;
41+
});
42+
43+
switch (themePref) {
44+
case PreferredTheme.auto:
45+
context.read<ThemeBloc>().add(
46+
const ChangedThemeEvent(
47+
AutoTheme(),
48+
),
49+
);
50+
break;
51+
case PreferredTheme.light:
52+
context.read<ThemeBloc>().add(
53+
const ChangedThemeEvent(
54+
LightTheme(),
55+
),
56+
);
57+
break;
58+
case PreferredTheme.dark:
59+
context.read<ThemeBloc>().add(
60+
const ChangedThemeEvent(
61+
DarkTheme(),
62+
),
63+
);
64+
break;
65+
}
66+
},
67+
),
68+
),
7169
],
7270
);
7371
}
@@ -92,21 +90,19 @@ class _ToggleJobViewButtonsState extends State<ToggleJobViewButtons> {
9290

9391
return Column(
9492
children: [
95-
...PreferredJobView.values
96-
.map<Widget>(
97-
(view) => RadioListTile<String>(
98-
title: Text(view.name),
99-
value: view.name,
100-
groupValue: _selectedView,
101-
onChanged: (_) async {
102-
await AppSettings.setJobView(view);
103-
setState(() {
104-
_selectedView = view.name;
105-
});
106-
},
107-
),
108-
)
109-
.toList(),
93+
...PreferredJobView.values.map<Widget>(
94+
(view) => RadioListTile<String>(
95+
title: Text(view.name),
96+
value: view.name,
97+
groupValue: _selectedView,
98+
onChanged: (_) async {
99+
await AppSettings.setJobView(view);
100+
setState(() {
101+
_selectedView = view.name;
102+
});
103+
},
104+
),
105+
),
110106
],
111107
);
112108
},

lib/custom_widgets/job_list_retriever.dart renamed to lib/components/job_list_retriever.dart

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import 'dart:async';
22

33
import 'package:flutter/material.dart';
4-
import 'package:katswiri/custom_widgets/custom_widgets.dart';
4+
import 'package:katswiri/components/components.dart';
55
import 'package:katswiri/models/models.dart';
66
import 'package:katswiri/sources/sources.dart';
77

8-
class JobListRetriever extends StatefulWidget {
9-
const JobListRetriever({
8+
class JobListingsRetriever extends StatefulWidget {
9+
const JobListingsRetriever({
1010
super.key,
1111
required this.source,
1212
this.filter,
@@ -18,11 +18,11 @@ class JobListRetriever extends StatefulWidget {
1818
final bool? primary;
1919

2020
@override
21-
State<JobListRetriever> createState() => _JobListRetrieverState();
21+
State<JobListingsRetriever> createState() => _JobListingsRetrieverState();
2222
}
2323

24-
class _JobListRetrieverState extends State<JobListRetriever>
25-
with AutomaticKeepAliveClientMixin<JobListRetriever> {
24+
class _JobListingsRetrieverState extends State<JobListingsRetriever>
25+
with AutomaticKeepAliveClientMixin<JobListingsRetriever> {
2626
late final Source _source;
2727
final List<Job> _jobs = [];
2828

@@ -120,8 +120,15 @@ class _JobListRetrieverState extends State<JobListRetriever>
120120

121121
if (_jobs.isEmpty && !_loading && _errMsg.isEmpty) {
122122
widgetList.add(
123-
const Center(
124-
child: Text('No Results Found'),
123+
Center(
124+
child: Column(
125+
children: [
126+
const Text('No Results Found'),
127+
RetryButton(
128+
onRetryPressed: _onRetryPressed,
129+
),
130+
],
131+
),
125132
),
126133
);
127134
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'
22
show CachedNetworkImageProvider;
33
import 'package:collection/collection.dart';
44
import 'package:flutter/material.dart';
5+
import 'package:flutter/services.dart';
56
import 'package:flutter_bloc/flutter_bloc.dart';
67
import 'package:katswiri/app_settings.dart';
78
import 'package:katswiri/bloc/bloc.dart';
@@ -26,6 +27,33 @@ class JobTile extends StatelessWidget {
2627
Widget build(BuildContext context) {
2728
return GestureDetector(
2829
onTapUp: (_) => _onTapUp(context),
30+
onLongPressUp: () {
31+
Clipboard.setData(
32+
ClipboardData(
33+
text: job.url,
34+
),
35+
).then((_) {
36+
ScaffoldMessenger.of(context).showSnackBar(
37+
const SnackBar(
38+
content: Text(
39+
'Copied to Clipboard',
40+
textAlign: TextAlign.center,
41+
style: TextStyle(
42+
color: Colors.white,
43+
),
44+
),
45+
backgroundColor: Colors.black,
46+
elevation: 8,
47+
margin: EdgeInsets.symmetric(
48+
horizontal: 32.0,
49+
vertical: 8.0,
50+
),
51+
behavior: SnackBarBehavior.floating,
52+
duration: Duration(milliseconds: 650),
53+
),
54+
);
55+
});
56+
},
2957
child: JobTileComponent(
3058
job: job,
3159
sourceIndex:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:flutter/material.dart';
2-
import 'package:katswiri/custom_widgets/job_list_retriever.dart';
2+
import 'package:katswiri/components/components.dart';
33
import 'package:katswiri/sources/sources.dart';
44

55
class TabbedSources extends StatefulWidget {
@@ -139,7 +139,7 @@ class _TabBarViewSectionState extends State<TabBarViewSection> {
139139
controller: widget.tabController,
140140
children: widget.sources
141141
.map<Widget>(
142-
(source) => JobListRetriever(
142+
(source) => JobListingsRetriever(
143143
source: source,
144144
filter: widget.filter,
145145
),

lib/screens/browse_jobs_screen.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:flutter/material.dart';
2-
import 'package:katswiri/custom_widgets/custom_widgets.dart';
2+
import 'package:katswiri/components/components.dart';
33
import 'package:katswiri/sources/sources.dart';
44

55
class BrowseJobsScreen extends StatelessWidget {

0 commit comments

Comments
 (0)