Skip to content

Commit

Permalink
fix #66
Browse files Browse the repository at this point in the history
* feat: support multiple rsshub domains

* feat: support multiple rsshub domains

* feat: support multiple rsshub domains
  • Loading branch information
LeetaoGoooo authored Dec 19, 2024
1 parent 6204d05 commit 588de30
Show file tree
Hide file tree
Showing 6 changed files with 392 additions and 244 deletions.
4 changes: 2 additions & 2 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ pluginManagement {
}

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "dev.flutter.flutter-plugin-loader" version "1.0.2"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
}

include ":app"
1 change: 1 addition & 0 deletions changelogs/3.0.4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat: support multiple rsshub domains #66
4 changes: 4 additions & 0 deletions lib/shared_prefs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class SharedPrefs {

String get domain => _sharedPrefs.getString("RSSHUB") ?? "https://rsshub.app";

List<String> get domains => _sharedPrefs.getStringList("DOMAIN") ?? ["https://rsshub.app"];

set domains(List<String> domains) => _sharedPrefs.setStringList("DOMAIN", domains);

/// Save history records after user delete one
set historyList(List<String> history) =>
_sharedPrefs.setStringList('historyListKey', history);
Expand Down
312 changes: 213 additions & 99 deletions lib/views/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:rssaid/common/common.dart';
import 'package:rssaid/shared_prefs.dart';
import 'package:rssaid/views/rules.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

import 'components/access_control.dart';
Expand All @@ -17,6 +16,8 @@ class _SettingPageState extends State<SettingPage> {
final SharedPrefs prefs = SharedPrefs();

String _domain = "https://rsshub.app";
late List<String> _domains;

PackageInfo packageInfo = PackageInfo(
appName: 'RSSAid',
packageName: 'Unknown',
Expand All @@ -32,11 +33,11 @@ class _SettingPageState extends State<SettingPage> {
}

Future<void> init() async {
if (prefs.domain.isNotEmpty) {
setState(() {
_domain = prefs.domain;
});
}
setState(() {
_domain = prefs.domain;
_domains = prefs.domains;
});

final info = await PackageInfo.fromPlatform();
setState(() {
packageInfo = info;
Expand All @@ -50,80 +51,203 @@ class _SettingPageState extends State<SettingPage> {
prefs.domain = domain;
}

void setDomains(List<String> domains) async {
setState(() {
_domains = domains;
});
prefs.domains = domains;
}

@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
title: Text(AppLocalizations.of(context)!.settings,
style: Theme.of(context).textTheme.titleLarge),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
})),
body: SingleChildScrollView(child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(padding: EdgeInsets.only(left: 24, right: 24, bottom: 8),
child: Text(AppLocalizations.of(context)!.common, style: Theme.of(context).textTheme.titleMedium,),
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
title: Text(AppLocalizations.of(context)!.settings,
style: Theme.of(context).textTheme.titleLarge),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
})),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 8),
child: Text(
AppLocalizations.of(context)!.common,
style: Theme.of(context).textTheme.titleMedium,
),
CommonRows(_domain, setDomain),
Padding(padding: EdgeInsets.only(left: 24, right: 24, bottom: 8),
child: Text(AppLocalizations.of(context)!.about, style: Theme.of(context).textTheme.titleMedium,),
),
CommonRows(
domain: _domain,
domains: _domains,
onDomainSet: (newDomain) {
setState(() {
_domain = newDomain;
prefs.domain = newDomain;
});
},
onDomainsSet: (newDomains) {
setState(() {
_domains = newDomains;
prefs.domains = newDomains;
});
},
),
Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 8),
child: Text(
AppLocalizations.of(context)!.about,
style: Theme.of(context).textTheme.titleMedium,
),
AboutRows(version: packageInfo.version,)
],
),),
);
),
AboutRows(
version: packageInfo.version,
)
],
),
),
);
}
}

// ignore: must_be_immutable
class CommonRows extends StatelessWidget {
String? _domain;
Function? _domainSetCallback;
TextEditingController _domainController = new TextEditingController();

CommonRows(String domain, Function domainSetFunc) {
this._domain = domain;
this._domainController.text = domain;
this._domainSetCallback = domainSetFunc;
class CommonRows extends StatefulWidget {
final String domain;
final List<String> domains;
final Function(String) onDomainSet;
final Function(List<String>) onDomainsSet;

const CommonRows({
Key? key,
required this.domain,
required this.domains,
required this.onDomainSet,
required this.onDomainsSet,
}) : super(key: key);

@override
_CommonRowsState createState() => _CommonRowsState();
}

class _CommonRowsState extends State<CommonRows> {
late TextEditingController _domainController;
late List<String> _localDomains;
late String _localDomain;

@override
void initState() {
super.initState();
_domainController = TextEditingController();
_localDomains = List.from(widget.domains);
_localDomain = widget.domain;
}

@override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
children: [
_buildHowUseSoftware(context),
_buildRssHubDomain(context),
AccessControlWidget(),
_buildRules(context)
],
);
void dispose() {
_domainController.dispose();
super.dispose();
}

Widget _buildRssHubDomain(BuildContext context) {
return Card(
margin: EdgeInsets.only(left: 24, right: 24, bottom: 8),
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 1,
child: ListTile(
leading: Icon(Icons.domain),
title: Text(
"RSSHub URL",
),
onTap: () {
_showDialog(context);
},
),

void _showDomainDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _domainController,
decoration: InputDecoration(
labelText: 'Add New Domain',
suffixIcon: IconButton(
icon: Icon(Icons.add),
onPressed: () {
if (_domainController.text.isNotEmpty &&
!_localDomains
.contains(_domainController.text.trim())) {
setState(() {
_localDomains.add(_domainController.text.trim());
widget.onDomainsSet(_localDomains);
});
_domainController.clear();
}
},
),
),
onSubmitted: (String domain) {
if (domain.isNotEmpty && !_localDomains.contains(domain.trim())) {
setState(() {
_localDomains.add(domain.trim());
widget.onDomainsSet(_localDomains);
});
_domainController.clear();
}
},
),
ListView.builder(
shrinkWrap: true,
itemCount: _localDomains.length,
itemBuilder: (context, index) {
final domain = _localDomains[index];
return Row(
children: [
Checkbox(
value: domain == _localDomain,
onChanged: (bool? selected) {
if (selected == true) {
setState(() {
widget.onDomainSet(domain);
_localDomain = domain;
});
}
},
),
Expanded(child: Text(domain)),
if (_localDomains.length > 1)
IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () {
if (_localDomains.length > 1) {
setState(() {
_localDomains.remove(domain);
widget.onDomainsSet(_localDomains);

// If the current domain is removed, select the first available domain
if (domain == widget.domain) {
widget.onDomainSet(_localDomains.first);
}
});
}
},
),
],
);
},
)
],
);
}),
actions: [
ElevatedButton(
child: Text('Ok'),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
}

Expand Down Expand Up @@ -169,39 +293,29 @@ class CommonRows extends StatelessWidget {
);
}

_showDialog(BuildContext context) async {
await showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return new AlertDialog(
// contentPadding: const EdgeInsets.all(16.0),
content: Container(
child: TextField(
controller: _domainController,
decoration: new InputDecoration(labelText: 'Host'),
),
),
actions: <Widget>[
TextButton(
child: Text(AppLocalizations.of(context)!.cancel),
onPressed: () {
Navigator.pop(context);
}),
ElevatedButton(
child: Text(AppLocalizations.of(context)!.sure),
onPressed: () {
if (_domainController.text != _domain) {
_domainSetCallback!(_domainController.text);
}
Navigator.pop(context);
})
],
);
},
);
});
Widget _buildRssHubDomain(BuildContext context) {
return Card(
margin: EdgeInsets.only(left: 24, right: 24, bottom: 8),
child: ListTile(
leading: Icon(Icons.domain),
title: Text("RSSHub URL"),
subtitle: Text(widget.domain),
onTap: () => _showDomainDialog(context),
),
);
}

@override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
children: [
_buildHowUseSoftware(context),
_buildRssHubDomain(context),
AccessControlWidget(),
_buildRules(context)
],
);
}
}

Expand Down
Loading

0 comments on commit 588de30

Please sign in to comment.