Skip to content
This repository has been archived by the owner on Jun 29, 2022. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
SchabanBo committed Jul 2, 2021
1 parent 5424acc commit aae473d
Show file tree
Hide file tree
Showing 15 changed files with 288 additions and 42 deletions.
43 changes: 40 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,58 @@
# qlevar_local_manager

This app will help you manage you applications locals easily. set you locals in groups, translate them with google translation and then export them to class to use with Getx.
This app will help you manage you applications locals easily. set you locals in groups, translate them with google translation and then export them to a class that is useable with Getx.

- [qlevar_local_manager](#qlevar_local_manager)
- [Getting Started](#getting-started)
- [Data Schema](#data-schema)
- [Translation](#translation)
- [Export](#export)
- [GetX](#getx)
- [Easy Localization](#easy-localization)
- [Quick Demo](#quick-demo)

## Getting Started

- launch the application
- add you first app
- The name of you app
- The path where to save the locals in form to reopen them (this should be in you repo files, so any update on you locals will be saved with the project)
- The path to export the generated local class to use it with GetX (Just the folder where the file should be generated)
- The path where to save the locals in form to reuse them later (this should be in you repo files, so any update on you locals will be saved with the project)
- The path where to export the generated files.
- Open you app.
- Add go.

## Data Schema

The data schema in the application is like json schema. Item and Node.
Every item has key and value. the value here is the translations in all defined languages.
Every Node can have many items and many node.

## Translation

you can translate the local using google translation. you need to set the google apiKey and click translate in the options button.
Only Local items can be translated. and this will translate only the empty locals for the selected item.

## Export

After adding all the data and translate them. you can export it and use it with [GetX](https://pub.dev/packages/get) or [EasyLocalization](https://pub.dev/packages/easy_localization)
In the AppBar click on Export and Export sheet will appear

### GetX

To export the data to file that matches [translations schema](https://github.com/jonataslaw/getx#translations)

- Chose Getx
- Pick the folder to export the class to.
- A file with name `locals.g.dart` will be generated in the folder and ready to use.

### Easy Localization

To export the data to json files with this [structure](https://github.com/aissat/easy_localization#-installation)

- Chose easyLocalization
- Pick the folder to export the files to.
- Json files will be generated every file has the name of language and contains the translations for this language.

## Quick Demo

https://user-images.githubusercontent.com/49782771/124182518-3ea80080-dab7-11eb-82a7-9919cc1b88ab.mp4
7 changes: 7 additions & 0 deletions lib/models/qlocal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ class QlevarLocalNode {
}
return result;
}

bool filter(String f) =>
key.contains(f) ||
items.any((i) => i.filter(f)) ||
nodes.any((i) => i.filter(f));
}

class QlevarLocalItem {
Expand All @@ -113,4 +118,6 @@ class QlevarLocalItem {
LocalItem getItem(String currentLan) {
return LocalItem(key: key, value: values[currentLan] ?? '');
}

bool filter(String f) => key.contains(f);
}
28 changes: 28 additions & 0 deletions lib/pages/export_page/controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:get/get.dart';
import '../../services/exporters/easy_localization_exporter_servvice.dart';
import '../main_page/controllers/main_controller.dart';
import '../../services/exporters/getx_exporter_servvice.dart';

class ExportController extends GetxController {
final RxString path = Get.find<MainController>().appfile.exportPath.obs;
final Rx<ExportAs> exportAs = ExportAs.getx.obs;

void export() {
final data = Get.find<MainController>().locals().toData();
switch (exportAs()) {
case ExportAs.getx:
GetxExporterService(data: data).export(path() + '/locals.g.dart');
break;
case ExportAs.easyLocalization:
EasyLocalizationExporterService(data: data).export(path());
break;
}

Get.back();
}
}

enum ExportAs {
easyLocalization,
getx,
}
6 changes: 2 additions & 4 deletions lib/pages/export_page/views/export_icon.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../main_page/controllers/main_controller.dart';
import 'export_view.dart';

class ExportIcon extends StatelessWidget {
Expand All @@ -9,9 +8,8 @@ class ExportIcon extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: () => Get.bottomSheet(
ExportView(path: Get.find<MainController>().appfile.exportPath)),
icon: const Icon(Icons.import_export),
onPressed: () => Get.bottomSheet(ExportView()),
icon: const Icon(Icons.upload),
tooltip: 'Export Data',
);
}
Expand Down
38 changes: 24 additions & 14 deletions lib/pages/export_page/views/export_view.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../helpers/colors.dart';
import '../controller.dart';
import '../../../helpers/path_picker.dart';
import '../../main_page/controllers/main_controller.dart';
import '../../../services/exporters/getx_exporter_servvice.dart';

class ExportView extends StatelessWidget {
final String path;
const ExportView({required this.path, Key? key}) : super(key: key);
final ExportController controller = ExportController();
ExportView({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
var _path = path;
return Container(
decoration: const BoxDecoration(
color: Colors.white,
Expand All @@ -22,19 +22,29 @@ class ExportView extends StatelessWidget {
children: [
const Text('Export Data', style: TextStyle(fontSize: 24)),
const Divider(),
Obx(() => Row(
children: ExportAs.values
.map((e) => Row(
mainAxisSize: MainAxisSize.min,
children: [
Radio<ExportAs>(
activeColor: AppColors.primary,
value: e,
groupValue: controller.exportAs(),
onChanged: controller.exportAs,
),
Text(describeEnum(e)),
],
))
.toList(),
)),
PathPicker(
path: path,
path: controller.path(),
title: 'Give the directory path to export to',
onChange: (s) => _path = s),
onChange: controller.path),
const Spacer(),
ElevatedButton(
onPressed: () {
final data = Get.find<MainController>().locals().toData();
GetxExporterService(data: data)
.export(_path + '/locals.dart');
Get.back();
},
child: const Text('Export')),
onPressed: controller.export, child: const Text('Export')),
],
),
),
Expand Down
37 changes: 37 additions & 0 deletions lib/pages/import_page/import_icon.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../helpers/path_picker.dart';
import '../../services/importers/json_import.dart';

class ImportIcon extends StatelessWidget {
const ImportIcon({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return IconButton(
onPressed: import,
icon: const Icon(Icons.download),
tooltip: 'Import Data',
);
}

void import() async {
var path = '';
await Get.defaultDialog(
title: 'Import',
middleText: 'Import language from json file',
content: PathPicker(
path: path,
title: 'Select file',
onChange: (s) => path = s,
type: PathType.file,
),
onConfirm: () => Get.back());
if (path.isEmpty) {
return;
}
final name =
path.substring(path.lastIndexOf('\\') + 1).replaceAll('.json', '');
await JsonFileImporter().import(path, name);
}
}
10 changes: 10 additions & 0 deletions lib/pages/main_page/controllers/main_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ import '../../../models/qlocal.dart';
class MainController extends GetxController {
final AppLocalFile appfile;
final Rx<QlevarLocal> locals;
final openAllNodes = false.obs;
final filter = ''.obs;
MainController({required this.appfile, required QlevarLocal locals})
: locals = locals.obs;

int get listItemsCount => locals().items.length + locals().nodes.length;

Iterable<QlevarLocalItem> get getItem => filter.isEmpty
? locals().items
: locals().items.where((i) => i.filter(filter()));

Iterable<QlevarLocalNode> get getNodes => filter.isEmpty
? locals().nodes
: locals().nodes.where((i) => i.filter(filter()));

void addItem(List<int> indexMap, String key) {
QlevarLocalNode node = locals();
for (var i = 1; i < indexMap.length; i++) {
Expand Down
19 changes: 18 additions & 1 deletion lib/pages/main_page/local_node/controller.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import 'package:get/get.dart';
import '../controllers/main_controller.dart';
import '../../../models/qlocal.dart';

class LocalNodeController extends GetxController {
final isOpen = false.obs;
late final isOpen = _mainController.openAllNodes.value.obs;
final Rx<QlevarLocalNode> item;
late final filter = _mainController.filter;
final List<int> indexMap;
final _mainController = Get.find<MainController>();

@override
void onInit() {
super.onInit();
_mainController.openAllNodes.listen(isOpen);
}

LocalNodeController(
QlevarLocalNode _item,
Expand All @@ -13,4 +22,12 @@ class LocalNodeController extends GetxController {
indexMap = List.from(_indexMap) {
indexMap.add(_item.index);
}

Iterable<QlevarLocalItem> get getItem => filter.isEmpty
? item().items
: item().items.where((i) => i.filter(filter()));

Iterable<QlevarLocalNode> get getNodes => filter.isEmpty
? item().nodes
: item().nodes.where((i) => i.filter(filter()));
}
31 changes: 17 additions & 14 deletions lib/pages/main_page/local_node/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,23 @@ class LocalNodeWidget extends StatelessWidget {
opacity: a,
child: SizeTransition(sizeFactor: a, child: c))),
child: controller.isOpen.isTrue
? ListView(shrinkWrap: true, children: [
...controller.item().items.map((e) => LocalItemBinder(
key: ValueKey(e.index),
item: e,
indexMap: controller.indexMap,
startPadding: 8 + startPadding,
)),
...controller.item().nodes.map((e) => LocalNodeBinder(
key: ValueKey(e.index),
item: e,
indexMap: controller.indexMap,
startPadding: 8 + startPadding,
)),
])
? ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: [
...controller.getItem.map((e) => LocalItemBinder(
key: ValueKey(e.index),
item: e,
indexMap: controller.indexMap,
startPadding: 8 + startPadding,
)),
...controller.getNodes.map((e) => LocalNodeBinder(
key: ValueKey(e.index),
item: e,
indexMap: controller.indexMap,
startPadding: 8 + startPadding,
)),
])
: const SizedBox()),
);
}
2 changes: 1 addition & 1 deletion lib/pages/main_page/views/add_language.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class AddLanguageIcon extends StatelessWidget {
con.locals().ensureAllLanguagesExist(con.locals().languages);
con.locals.refresh();
},
icon: const Icon(Icons.add_comment));
icon: const Icon(Icons.language));
}
}

Expand Down
10 changes: 7 additions & 3 deletions lib/pages/main_page/views/main_view.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../import_page/import_icon.dart';
import 'options_row.dart';
import 'exit_icon.dart';
import 'add_language.dart';
import '../local_item/controller.dart';
Expand All @@ -23,6 +25,7 @@ class MainView extends GetView<MainController> {
actions: const [
SaveDataWidget(),
ExportIcon(),
ImportIcon(),
AddLanguageIcon(),
SettingsIcon(),
ExitIcon(),
Expand All @@ -34,6 +37,7 @@ class MainView extends GetView<MainController> {

Widget get _buildList => Obx(() => Column(
children: [
OptionsRow(),
// ignore: prefer_const_literals_to_create_immutables
Card(
child: LocalItemWidget(
Expand All @@ -45,15 +49,15 @@ class MainView extends GetView<MainController> {
isHeader: true,
)),
Expanded(
child: ListView(children: [
...controller.locals().items.map((e) => LocalItemBinder(
child: ListView(shrinkWrap: true, primary: true, children: [
...controller.getItem.map((e) => LocalItemBinder(
key: ValueKey(e.index),
item: e,
// ignore: prefer_const_literals_to_create_immutables
indexMap: [0],
startPadding: 8,
)),
...controller.locals().nodes.map((e) => LocalNodeBinder(
...controller.getNodes.map((e) => LocalNodeBinder(
key: ValueKey(e.index),
item: e,
// ignore: prefer_const_literals_to_create_immutables
Expand Down
Loading

0 comments on commit aae473d

Please sign in to comment.