Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

設定のインポート・エクスポートのダイアログ修正 #208

Merged
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
109 changes: 64 additions & 45 deletions lib/repository/import_export_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,36 @@ class ImportExportRepository extends ChangeNotifier {
ImportExportRepository(this.reader);

Future<void> import(BuildContext context, Account account) async {
final folder = await showDialog<DriveFolder>(
barrierDismissible: false,
final result = await showDialog<FolderResult>(
context: context,
builder: (context2) => WillPopScope(
onWillPop: () async => false,
child: FolderSelectDialog(
account: account,
fileShowTarget: const ["miria.json", "miria.json.unknown"],
),
builder: (context2) => FolderSelectDialog(
account: account,
fileShowTarget: const ["miria.json", "miria.json.unknown"],
confirmationText: "このフォルダーからインポートする",
),
);
if (result == null) return;

var alreadyExists = await reader(misskeyProvider(account))
.drive
.files
.find(DriveFilesFindRequest(name: "miria.json", folderId: folder?.id));
final folder = result.folder;

Iterable<DriveFile> alreadyExists =
await reader(misskeyProvider(account)).drive.files.find(
DriveFilesFindRequest(
name: "miria.json",
folderId: folder?.id,
),
);

if (!context.mounted) return;
if (alreadyExists.isEmpty) {
alreadyExists = await reader(misskeyProvider(account)).drive.files.find(
DriveFilesFindRequest(
name: "miria.json.unknown", folderId: folder?.id));
DriveFilesFindRequest(
name: "miria.json.unknown",
folderId: folder?.id,
),
);

if (!context.mounted) return;
if (alreadyExists.isEmpty) {
await SimpleMessageDialog.show(context, "ここにMiriaの設定ファイルあれへんかったわ");
return;
Expand Down Expand Up @@ -82,9 +90,11 @@ class ImportExportRepository extends ChangeNotifier {
final tabSettings = <TabSetting>[];

for (final tabSetting in json["tabSettings"]) {
final account = accounts.firstWhereOrNull((element) =>
tabSetting["account"]["host"] == element.host &&
tabSetting["account"]["userId"] == element.userId);
final account = accounts.firstWhereOrNull(
(element) =>
tabSetting["account"]["host"] == element.host &&
tabSetting["account"]["userId"] == element.userId,
);

if (account == null) {
continue;
Expand All @@ -95,43 +105,51 @@ class ImportExportRepository extends ChangeNotifier {
(tabSetting as Map<String, dynamic>)
..remove("account")
..addEntries(
[MapEntry("account", jsonDecode(jsonEncode(account.toJson())))]);
[MapEntry("account", jsonDecode(jsonEncode(account.toJson())))],
);

tabSettings.add(TabSetting.fromJson(tabSetting));
}
reader(tabSettingsRepositoryProvider).save(tabSettings);

if (!context.mounted) return;
await SimpleMessageDialog.show(context, "インポート終わったで。");

if (!context.mounted) return;
context.router
..removeWhere((route) => true)
..push(const SplashRoute());
}

Future<void> export(BuildContext context, Account account) async {
final folder = await showDialog<DriveFolder>(
barrierDismissible: false,
final result = await showDialog<FolderResult>(
context: context,
builder: (context2) => WillPopScope(
onWillPop: () async => false,
child: FolderSelectDialog(
account: account,
fileShowTarget: const ["miria.json", "miria.json.unknown"],
),
builder: (context2) => FolderSelectDialog(
account: account,
fileShowTarget: const ["miria.json", "miria.json.unknown"],
confirmationText: "このフォルダーに保存する",
),
);
if (result == null) return;

final folder = result.folder;

final alreadyExists = await reader(misskeyProvider(account))
.drive
.files
.find(DriveFilesFindRequest(
name: "miria.json.unknown", folderId: folder?.id));
final alreadyExists =
await reader(misskeyProvider(account)).drive.files.find(
DriveFilesFindRequest(
name: "miria.json.unknown",
folderId: folder?.id,
),
);

if (!context.mounted) return;
if (alreadyExists.isNotEmpty) {
final alreadyConfirm = await SimpleConfirmDialog.show(
context: context,
message: "ここにもうあるけど上書きするか?",
primary: "上書きする",
secondary: "やっぱやめた");
context: context,
message: "ここにもうあるけど上書きするか?",
primary: "上書きする",
secondary: "やっぱやめた",
);
if (alreadyConfirm != true) return;

for (final element in alreadyExists) {
Expand All @@ -143,13 +161,11 @@ class ImportExportRepository extends ChangeNotifier {
}

final data = ExportedSetting(
generalSettings: reader(generalSettingsRepositoryProvider).settings,
tabSettings:
reader(tabSettingsRepositoryProvider).tabSettings.toList(),
accountSettings: reader(accountSettingsRepositoryProvider)
.accountSettings
.toList())
.toJson();
generalSettings: reader(generalSettingsRepositoryProvider).settings,
tabSettings: reader(tabSettingsRepositoryProvider).tabSettings.toList(),
accountSettings:
reader(accountSettingsRepositoryProvider).accountSettings.toList(),
).toJson();

// 外に漏れると困るので
for (final element in data["tabSettings"] as List) {
Expand All @@ -159,13 +175,16 @@ class ImportExportRepository extends ChangeNotifier {
}

await reader(misskeyProvider(account)).drive.files.createAsBinary(
DriveFilesCreateRequest(
DriveFilesCreateRequest(
folderId: folder?.id,
name: "miria.json",
comment: "Miria設定ファイル",
force: true),
Uint8List.fromList(utf8.encode(jsonEncode(data))));
force: true,
),
Uint8List.fromList(utf8.encode(jsonEncode(data))),
);

if (!context.mounted) return;
await SimpleMessageDialog.show(context, "エクスポート終わったで");
}
}
115 changes: 68 additions & 47 deletions lib/view/settings_page/import_export_page/folder_select_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ import 'package:miria/view/common/futable_list_builder.dart';
import 'package:miria/view/common/pushable_listview.dart';
import 'package:misskey_dart/misskey_dart.dart';

class FolderResult {
const FolderResult(this.folder);

final DriveFolder? folder;
}

class FolderSelectDialog extends ConsumerStatefulWidget {
final Account account;
final List<String>? fileShowTarget;
final String confirmationText;

const FolderSelectDialog({
super.key,
required this.account,
required this.fileShowTarget,
required this.confirmationText,
});

@override
Expand All @@ -29,17 +37,18 @@ class FolderSelectDialogState extends ConsumerState<FolderSelectDialog> {
return AlertDialog(
title: Column(
children: [
const Text("フォルダ選択"),
const Text("フォルダー選択"),
Row(
children: [
if (path.isNotEmpty)
IconButton(
onPressed: () {
setState(() {
path.removeLast();
});
},
icon: const Icon(Icons.arrow_back)),
onPressed: () {
setState(() {
path.removeLast();
});
},
icon: const Icon(Icons.arrow_back),
),
Expanded(child: Text(path.map((e) => e.name).join("/"))),
],
)
Expand All @@ -52,54 +61,65 @@ class FolderSelectDialogState extends ConsumerState<FolderSelectDialog> {
child: Column(
children: [
PushableListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
initializeFuture: () async {
final misskey = ref.read(misskeyProvider(widget.account));
final response = await misskey.drive.folders.folders(
DriveFoldersRequest(
folderId: path.isEmpty ? null : path.last.id));
return response.toList();
},
nextFuture: (lastItem, _) async {
final misskey = ref.read(misskeyProvider(widget.account));
final response = await misskey.drive.folders.folders(
DriveFoldersRequest(
untilId: lastItem.id,
folderId: path.isEmpty ? null : path.last.id));
return response.toList();
},
listKey: path.map((e) => e.id).join("/"),
itemBuilder: (context, item) {
return ListTile(
leading: const Icon(Icons.folder),
title: Text(item.name ?? ""),
onTap: () {
setState(() {
path.add(item);
});
},
);
}),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
initializeFuture: () async {
final misskey = ref.read(misskeyProvider(widget.account));
final response = await misskey.drive.folders.folders(
DriveFoldersRequest(
folderId: path.isEmpty ? null : path.last.id,
),
);
return response.toList();
},
nextFuture: (lastItem, _) async {
final misskey = ref.read(misskeyProvider(widget.account));
final response = await misskey.drive.folders.folders(
DriveFoldersRequest(
untilId: lastItem.id,
folderId: path.isEmpty ? null : path.last.id,
),
);
return response.toList();
},
listKey: path.map((e) => e.id).join("/"),
itemBuilder: (context, item) {
return ListTile(
leading: const Icon(Icons.folder),
title: Text(item.name ?? ""),
onTap: () {
setState(() {
path.add(item);
});
},
);
},
),
if (widget.fileShowTarget != null)
FutureListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
future: () async {
final list = [];
for (final element in widget.fileShowTarget!) {
list.addAll(await ref
.read(misskeyProvider(widget.account))
.drive
.files
.find(DriveFilesFindRequest(
folderId: path.lastOrNull?.id, name: element)));
list.addAll(
await ref
.read(misskeyProvider(widget.account))
.drive
.files
.find(
DriveFilesFindRequest(
folderId: path.lastOrNull?.id,
name: element,
),
),
);
}
return list.toList();
}(),
builder: (context, item) => Row(
children: [
Icon(Icons.description),
const Icon(Icons.description),
Expanded(child: Text(item.name)),
],
),
Expand All @@ -110,10 +130,11 @@ class FolderSelectDialogState extends ConsumerState<FolderSelectDialog> {
),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(path.lastOrNull);
},
child: const Text("このフォルダーに保存する"))
onPressed: () {
Navigator.of(context).pop(FolderResult(path.lastOrNull));
},
child: Text(widget.confirmationText),
)
],
);
}
Expand Down
Loading
Loading