Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
tsutsu3 committed Feb 24, 2025
1 parent f01ac8f commit 5c330ae
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 70 deletions.
1 change: 0 additions & 1 deletion lib/gateways/v6/api_gateway_v6.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:pi_hole_client/functions/conversions.dart';
import 'package:pi_hole_client/functions/logger.dart';
import 'package:pi_hole_client/gateways/api_gateway_interface.dart';
import 'package:pi_hole_client/models/api/v6/auth/auth.dart' show Session;
Expand Down
52 changes: 52 additions & 0 deletions lib/providers/domains_list_provider.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:pi_hole_client/constants/enums.dart';
import 'package:pi_hole_client/models/domain.dart';
Expand Down Expand Up @@ -141,4 +142,55 @@ class DomainsListProvider with ChangeNotifier {
}
notifyListeners();
}

Domain? getDomainById(int id) {
final whitelistDomain = _whitelistDomains.firstWhereOrNull(
(item) => item.id == id,
);

if (whitelistDomain != null) {
return whitelistDomain;
}

final blacklistDomain = _blacklistDomains.firstWhereOrNull(
(item) => item.id == id,

Check warning on line 156 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L155-L156

Added lines #L155 - L156 were not covered by tests
);

return blacklistDomain;
}

/// Update domain
void updateDomain(Domain domain) {

Check warning on line 163 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L163

Added line #L163 was not covered by tests
// TODO: Handle changes when white and black lists are updated
// whitelist
if (domain.type == 0 || domain.type == 2) {

Check warning on line 166 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L166

Added line #L166 was not covered by tests
final index =
_whitelistDomains.indexWhere((item) => item.id == domain.id);
if (index != -1) {
_whitelistDomains[index] = domain;

Check warning on line 170 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L168-L170

Added lines #L168 - L170 were not covered by tests
}

final filteredIndex =
_filteredWhitelistDomains.indexWhere((item) => item.id == domain.id);
if (filteredIndex != -1) {
_filteredWhitelistDomains[filteredIndex] = domain;

Check warning on line 176 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L174-L176

Added lines #L174 - L176 were not covered by tests
}
}

// blacklist
if (domain.type == 1 || domain.type == 3) {

Check warning on line 181 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L181

Added line #L181 was not covered by tests
final index =
_blacklistDomains.indexWhere((item) => item.id == domain.id);
if (index != -1) {
_blacklistDomains[index] = domain;

Check warning on line 185 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L183-L185

Added lines #L183 - L185 were not covered by tests
}

final filteredIndex =
_filteredBlacklistDomains.indexWhere((item) => item.id == domain.id);
if (filteredIndex != -1) {
_filteredBlacklistDomains[filteredIndex] = domain;

Check warning on line 191 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L189-L191

Added lines #L189 - L191 were not covered by tests
}
}
notifyListeners();

Check warning on line 194 in lib/providers/domains_list_provider.dart

View check run for this annotation

Codecov / codecov/patch

lib/providers/domains_list_provider.dart#L194

Added line #L194 was not covered by tests
}
}
56 changes: 22 additions & 34 deletions lib/screens/domains/domain_comment_modal.dart
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
import 'package:flutter/material.dart';
import 'package:pi_hole_client/l10n/generated/app_localizations.dart';
import 'package:pi_hole_client/models/domain.dart';
import 'package:pi_hole_client/providers/servers_provider.dart';
import 'package:provider/provider.dart';

class DomainCommentModal extends StatefulWidget {
const DomainCommentModal({required this.domain, super.key});
const DomainCommentModal({

Check warning on line 6 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L6

Added line #L6 was not covered by tests
required this.domain,
required this.readonly,
super.key,
});

final Domain domain;
final bool readonly;

@override
State<DomainCommentModal> createState() => _DomainCommentModalState();

Check warning on line 16 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L15-L16

Added lines #L15 - L16 were not covered by tests
}

class _DomainCommentModalState extends State<DomainCommentModal> {
late TextEditingController _commentController;
late bool readonly = widget.readonly;

bool isSaveEnabled = false;
bool isEditable = false;

@override

Check warning on line 25 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L25

Added line #L25 was not covered by tests
void initState() {
super.initState();

final serversProvider =
Provider.of<ServersProvider>(context, listen: false);
final apiGateway = serversProvider.selectedApiGateway;

isEditable = apiGateway?.server.apiVersion != 'v5';

_commentController = TextEditingController(text: widget.domain.comment);

if (isEditable) {
_commentController.addListener(() {
setState(() {
isSaveEnabled = _commentController.text.isNotEmpty;
});
_commentController.addListener(() {
setState(() {
isSaveEnabled = _commentController.text.isNotEmpty;

Check warning on line 31 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L27-L31

Added lines #L27 - L31 were not covered by tests
});
}
});
}

@override

Check warning on line 36 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L36

Added line #L36 was not covered by tests
Expand All @@ -47,9 +41,6 @@ class _DomainCommentModalState extends State<DomainCommentModal> {

@override
Widget build(BuildContext context) {
final serversProvider = Provider.of<ServersProvider>(context);
final apiGateway = serversProvider.selectedApiGateway;

return AlertDialog(
scrollable: true,
title: Column(
Expand All @@ -68,37 +59,34 @@ class _DomainCommentModalState extends State<DomainCommentModal> {
),
],
),
content: isEditable
content: readonly

Check warning on line 62 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L62

Added line #L62 was not covered by tests
// v5: read only, because the API does not support updating comments
? Text(
widget.domain.comment == ''
? AppLocalizations.of(context)!.noComment
: widget.domain.comment!,
style: TextStyle(fontSize: 16, color: Colors.grey[700]),

Check warning on line 68 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L64-L68

Added lines #L64 - L68 were not covered by tests
)
// v6: editable
? TextField(
: TextField(
controller: _commentController,
onChanged: (value) {
setState(() {});

Check warning on line 74 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L71-L74

Added lines #L71 - L74 were not covered by tests
},
decoration: InputDecoration(
hintText: AppLocalizations.of(context)!.enterComment,

Check warning on line 77 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L76-L77

Added lines #L76 - L77 were not covered by tests
),
)
// v5: read only, because the API does not support updating comments
: Text(
widget.domain.comment == ''
? AppLocalizations.of(context)!.noComment
: widget.domain.comment!,
style: TextStyle(fontSize: 16, color: Colors.grey[700]),
),
actions: [
TextButton(
onPressed: () => Navigator.maybePop(context, widget.domain.comment),
child: Text(AppLocalizations.of(context)!.cancel),

Check warning on line 83 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L82-L83

Added lines #L82 - L83 were not covered by tests
),
const SizedBox(width: 14),
if (isEditable)
if (!readonly)
TextButton(
onPressed: isSaveEnabled
? () async {
final newDomain = widget.domain
.copyWith(comment: _commentController.text);
await apiGateway?.updateDomain(newDomain);
await Navigator.maybePop(context, _commentController.text);

Check warning on line 90 in lib/screens/domains/domain_comment_modal.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_comment_modal.dart#L86-L90

Added lines #L86 - L90 were not covered by tests
}
: null,
Expand Down
98 changes: 65 additions & 33 deletions lib/screens/domains/domain_details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,26 @@ import 'package:pi_hole_client/functions/conversions.dart';
import 'package:pi_hole_client/functions/format.dart';
import 'package:pi_hole_client/l10n/generated/app_localizations.dart';
import 'package:pi_hole_client/models/domain.dart';
import 'package:pi_hole_client/models/gateways.dart';
import 'package:pi_hole_client/providers/domains_list_provider.dart';
import 'package:pi_hole_client/providers/servers_provider.dart';
import 'package:pi_hole_client/screens/domains/delete_domain_modal.dart';
import 'package:pi_hole_client/screens/domains/domain_comment_modal.dart';
import 'package:pi_hole_client/widgets/custom_list_tile.dart';
import 'package:provider/provider.dart';

class DomainDetailsScreen extends StatefulWidget {
class DomainDetailsScreen extends StatelessWidget {
const DomainDetailsScreen({
required this.domain,
required this.remove,
super.key,
this.colors,
});

final Domain domain;
final Domain domain; // useonly id
final void Function(Domain) remove;
final AppColors? colors;

@override
State<DomainDetailsScreen> createState() => _DomainDetailsScreenState();
}

class _DomainDetailsScreenState extends State<DomainDetailsScreen> {
late Domain domain; // 更新可能な domain を保持

@override
void initState() {
super.initState();
domain = widget.domain; // 初期値をセット
}

Widget actionCustomListTile({
required IconData leadingIcon,
required String label,
Expand All @@ -59,6 +50,40 @@ class _DomainDetailsScreenState extends State<DomainDetailsScreen> {

@override
Widget build(BuildContext context) {
final domainProvider = Provider.of<DomainsListProvider>(context);
final serverProvider = Provider.of<ServersProvider>(context, listen: false);
final apiGateway = serverProvider.selectedApiGateway;
var newDomain = domainProvider.getDomainById(domain.id);

if (newDomain == null) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.domainDetails),

Check warning on line 61 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L59-L61

Added lines #L59 - L61 were not covered by tests
),
body: Center(
child: Column(

Check warning on line 64 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L63-L64

Added lines #L63 - L64 were not covered by tests
mainAxisAlignment: MainAxisAlignment.center,
children: [

Check warning on line 66 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L66

Added line #L66 was not covered by tests
const Icon(
Icons.error,
size: 50,
color: Colors.red,
),
const SizedBox(height: 50),
Text(
AppLocalizations.of(context)!.domainNotExists,

Check warning on line 74 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L73-L74

Added lines #L73 - L74 were not covered by tests
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant,

Check warning on line 77 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L76-L77

Added lines #L76 - L77 were not covered by tests
fontSize: 22,
),
),
],
),
),
);
}

return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.domainDetails),
Expand All @@ -69,7 +94,7 @@ class _DomainDetailsScreenState extends State<DomainDetailsScreen> {
builder: (context) => DeleteDomainModal(
onConfirm: () {
Navigator.maybePop(context);
widget.remove(domain);
remove(domain);
},
),
),
Expand All @@ -84,52 +109,59 @@ class _DomainDetailsScreenState extends State<DomainDetailsScreen> {
CustomListTile(
leadingIcon: Icons.domain,
label: AppLocalizations.of(context)!.domain,
description: domain.domain,
description: newDomain.domain,
),
CustomListTile(
leadingIcon: Icons.category_rounded,
label: AppLocalizations.of(context)!.type,
description: getDomainType(domain.type),
color: widget.colors != null
? convertColorFromNumber(widget.colors!, domain.type)
description: getDomainType(newDomain.type),
color: colors != null
? convertColorFromNumber(colors!, newDomain.type)
: null,
),
CustomListTile(
leadingIcon: Icons.schedule_rounded,
label: AppLocalizations.of(context)!.dateAdded,
description: formatTimestamp(domain.dateAdded, 'yyyy-MM-dd'),
description: formatTimestamp(newDomain.dateAdded, 'yyyy-MM-dd'),
),
CustomListTile(
leadingIcon: Icons.update_rounded,
label: AppLocalizations.of(context)!.dateModified,
description: formatTimestamp(domain.dateModified, 'yyyy-MM-dd'),
description:
formatTimestamp(newDomain.dateModified, 'yyyy-MM-dd'),
),
CustomListTile(
leadingIcon: Icons.check,
label: AppLocalizations.of(context)!.status,
description: domain.enabled == 1
description: newDomain.enabled == 1
? AppLocalizations.of(context)!.enabled
: AppLocalizations.of(context)!.disabled,
),
// Comment
actionCustomListTile(
leadingIcon: Icons.comment_rounded,
label: AppLocalizations.of(context)!.comment,
description: domain.comment == '' || domain.comment == null
description: newDomain.comment == '' || newDomain.comment == null
? AppLocalizations.of(context)!.noComment
: domain.comment,
: newDomain.comment,
onTap: () async {
final updatedComment = await showModal<String>(
final newComment = await showModal<String>(

Check warning on line 148 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L146-L148

Added lines #L146 - L148 were not covered by tests
context: context,
builder: (context) => DomainCommentModal(domain: domain),
builder: (context) => DomainCommentModal(

Check warning on line 150 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L150

Added line #L150 was not covered by tests
domain: newDomain!,
readonly:
apiGateway!.server.apiVersion == 'v5' ? true : false,

Check warning on line 153 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L153

Added line #L153 was not covered by tests
),
);

if (updatedComment != null &&
updatedComment != domain.comment) {
setState(() {
domain =
domain.copyWith(comment: updatedComment); // コメントを更新
});
if (newComment != null && newComment != newDomain!.comment) {
if (context.mounted) {
newDomain = newDomain!.copyWith(comment: newComment);
final resp = await apiGateway!.updateDomain(newDomain!);
if (resp.result == APiResponseType.success) {
domainProvider.updateDomain(newDomain!);

Check warning on line 162 in lib/screens/domains/domain_details_screen.dart

View check run for this annotation

Codecov / codecov/patch

lib/screens/domains/domain_details_screen.dart#L157-L162

Added lines #L157 - L162 were not covered by tests
}
}
}
},
trailing: Icon(
Expand Down
2 changes: 1 addition & 1 deletion lib/screens/domains/domains.dart
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class _DomainListsWidgetState extends State<DomainListsWidget>
flex: 3,
child: selectedDomain != null
? DomainDetailsScreen(
domain: selectedDomain!,
domain: selectedDomain!.copyWith(),
remove: (domain) {
setState(() => selectedDomain = null);
removeDomain(domain);
Expand Down
2 changes: 1 addition & 1 deletion lib/screens/domains/domains_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class _DomainsListState extends State<DomainsList> {
context,
MaterialPageRoute(
builder: (context) => DomainDetailsScreen(
domain: d,
domain: d.copyWith(),
remove: removeDomain,
colors: serversProvider.colors,
),
Expand Down

0 comments on commit 5c330ae

Please sign in to comment.