Compare commits

...

12 Commits
master ... main

Author SHA1 Message Date
83c1c1b67f
Changed branch 2022-10-28 10:43:07 +07:00
a472156d22
Add base model 2022-10-28 10:33:56 +07:00
3b2abdc030 Updated and fixed
All checks were successful
continuous-integration/drone/push Build is passing
2021-09-11 17:36:11 +07:00
34ce6f3e9b Update '.drone.yml'
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2021-09-11 17:34:58 +07:00
2b31d30228 Task: Add dart test for run testing project 2021-09-11 17:34:31 +07:00
5904c44789 Task: Add drone ci for cubetiq dart shared 2021-09-11 17:22:52 +07:00
51f7293977 Task: Add show for xlogger function 2021-06-17 18:27:50 +07:00
635e3b49a1 Release to 1.0.1 2021-06-17 15:48:49 +07:00
5915aafb95 Task: Add i18n translator and factory for translatable for text formatter and default factory 2021-06-17 15:25:40 +07:00
84c0e44b87 Task: Add logger for log debug for function to replace console log 2021-06-11 19:48:51 +07:00
f555d68a29 Task: Add my cart code example to explain a local cart mutable 2021-06-09 14:33:18 +07:00
57cded1c79 Task: Add format number with precision and updated for dart shared 2021-06-07 17:50:04 +07:00
21 changed files with 330 additions and 19 deletions

14
.drone.yml Normal file
View File

@ -0,0 +1,14 @@
kind: pipeline
type: exec
name: default
platform:
os: darwin
arch: amd64
steps:
- name: flutter-dart-version
commands:
- flutter --version
- dart --version
- name: test
commands:
- dart test

View File

@ -2,9 +2,9 @@ name: Dart
on:
push:
branches: [ master ]
branches: [ main ]
pull_request:
branches: [ master ]
branches: [ main ]
jobs:
build:

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ build/
# Omit committing pubspec.lock for library packages; see
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock
.dccache

View File

@ -2,3 +2,9 @@
- Configurable
- Text Formatter
## 1.0.1
- Add translator provider
- Enhanced text formatter able to translate by options
- Fixed text formatter params and args for optional

View File

@ -0,0 +1,7 @@
import 'package:cubetiq/src/text/functions.dart';
import 'package:cubetiq/src/xlog/xlog.dart';
void main(List<String> args) {
XLog.debug(StringUtils.format(10.5555, 2));
XLog.debug(StringUtils.formatFromString('10.5555', 2));
}

View File

@ -3,8 +3,8 @@ import 'package:cubetiq/text.dart';
void main(List<String> args) {
var text1 = 'Hello, {0}, then do this it by {1}!';
var text2 = 'Hello, {firstName}, then do this it by {lastName}!';
var result1 = TextFormatter(text1).format(['Sambo', 'Chea']);
var result2 = TextFormatter(text2).decorate({
var result1 = TextFormatter(text1).format(args: ['Sambo', 'Chea']);
var result2 = TextFormatter(text2).decorate(params: {
'firstName': 'Sambo',
'lastName': 'Chea',
});

View File

@ -0,0 +1,36 @@
import 'package:cubetiq/text.dart';
import 'package:cubetiq/i18n_translator.dart';
void main(List<String> args) {
var text = 'Your name is {name}!';
// Before set provider
var result = StringUtils.decorator(text, translate: true, params: {
'name': 'Sambo Chea',
});
print('Result Before => $result');
TranslatorFactory.setProvider(TranslatorProviderExample());
// After set provider
result = StringUtils.decorator(text, translate: true, params: {
'name': 'Sambo Chea',
});
print('Result After => $result');
}
class TranslatorProviderExample implements TranslatorProvider {
@override
bool hasKey(String key) {
return false;
}
@override
String translate(String key,
{Map<String, dynamic>? params, String? fallback}) {
if (key == 'Your name is {name}!') {
return 'ឈ្មោះរបស់អ្នកគឺ {name}!';
}
return key;
}
}

View File

@ -0,0 +1,91 @@
import 'package:cubetiq/model.dart';
void main(List<String> args) {
MyCart.addCart(
Cart(id: 1, name: 'Apple', qty: 1),
);
MyCart.show();
MyCart.addCart(
Cart(id: 1, name: 'Apple', qty: 2),
);
MyCart.show();
MyCart.inc(1, qty: 2);
MyCart.show();
MyCart.dec(1, qty: 4);
MyCart.show();
}
class Cart extends BaseModel<Cart> {
final int id;
final String? name;
double qty;
Cart({this.id = -1, this.name, this.qty = 0});
@override
Cart fromMap(Map<String, dynamic> map) {
return Cart(
id: map['id'],
name: map['name'],
qty: map['qty'],
);
}
@override
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'qty': qty,
};
}
}
class MyCart {
static final Map<int, Cart> carts = {};
static void inc(int id, {double qty = 1}) {
if (carts.containsKey(id)) {
carts[id]!.qty += qty;
}
}
static void dec(int id, {double qty = 1}) {
if (carts.containsKey(id)) {
carts[id]!.qty -= qty;
}
}
static void addCart(Cart cart) {
if (carts.containsKey(cart.id)) {
carts[cart.id]!.qty += cart.qty;
} else {
carts[cart.id] = cart;
}
}
static void removeCart(Cart cart) {
if (carts.containsKey(cart.id)) {
carts.remove(cart.id);
}
}
static void show() {
var data = carts.map((key, value) => MapEntry(key, value));
var json = data.map((key, value) => MapEntry(key, value.toJson()));
var model = json.map((key, value) => MapEntry(key, Cart().fromJson(value)));
print('================ Map =================');
print('$data');
print('================ Json =================');
print('$json');
print('================ Model =================');
print('$model');
}
}

4
lib/i18n_translator.dart Normal file
View File

@ -0,0 +1,4 @@
library i18n_translator;
export 'src/i18n/translator_provider.dart';
export 'src/i18n/translator_factory.dart';

3
lib/model.dart Normal file
View File

@ -0,0 +1,3 @@
library model;
export 'src/model/base.dart';

View File

@ -0,0 +1,34 @@
import 'translator_provider.dart';
/// Translate Factory
///
/// @author sombochea
/// @since 1.0.0
class TranslatorFactory {
static TranslatorProvider? _provider;
static void setProvider(TranslatorProvider provider) {
_provider = provider;
}
static bool hasProvider() => _provider != null;
static bool hasKey(String key) {
if (hasProvider()) {
return _provider!.hasKey(key);
}
return false;
}
static String translate(
String key, {
Map<String, dynamic>? params,
String? fallback,
}) {
if (hasProvider()) {
return _provider!.translate(key, params: params, fallback: fallback);
}
return fallback ?? key;
}
}

View File

@ -0,0 +1,9 @@
/// Translate Provider
///
/// @author sombochea
/// @since 1.0.0
abstract class TranslatorProvider {
bool hasKey(String key);
String translate(String key,
{Map<String, dynamic>? params, String? fallback});
}

33
lib/src/model/base.dart Normal file
View File

@ -0,0 +1,33 @@
import 'dart:convert';
abstract class BaseModel<T> {
BaseModel();
Map<String, dynamic> toMap();
T fromMap(Map<String, dynamic> map);
T fromJson(String json) {
return fromMap(decode(json));
}
@override
String toString() {
return toMap().toString();
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is BaseModel && other.toMap() == toMap();
}
@override
int get hashCode => toMap().hashCode;
String toJson() => encode(toMap());
dynamic decode(String json) => jsonDecode(json);
String encode(dynamic json) => jsonEncode(json);
}

View File

@ -7,10 +7,11 @@ extension StringExtensionOnNonull on String {
}
extension StringExtensionOnNullable on String? {
String? textFormat(List<dynamic> args) => StringUtils.textFormat(this, args);
String? textFormat({List<dynamic>? args, bool translate = false}) =>
StringUtils.textFormat(this, args: args, translate: translate);
String? decorator(Map<String, dynamic> params) =>
StringUtils.decorator(this, params);
String? decorator({Map<String, dynamic>? params, bool translate = false}) =>
StringUtils.decorator(this, params: params, translate: translate);
bool get isBlank {
if (this == null) return true;
@ -32,4 +33,8 @@ extension StringExtensionOnNullable on String? {
bool get isNullOrEmptyOrBlank => StringUtils.isNullOrEmptyOrBlank(this);
bool get isEqualsIgnoreCase => StringUtils.equalsIgnoreCase(this, this);
String toPrecision([int precision = 2]) {
return StringUtils.formatFromString(this, precision);
}
}

View File

@ -6,13 +6,26 @@ class StringUtils {
return n.toStringAsFixed(n.truncateToDouble() == n ? precision : precision);
}
/// Format number from String with precision
static String formatFromString(String? text, [int precision = 2]) {
text ??= '0.0';
var n = double.parse(text);
return n.toStringAsFixed(n.truncateToDouble() == n ? precision : precision);
}
/// Text formatter with custom args
static TextFormatter textFormatter(String? text, {bool translate = false}) =>
TextFormatter(text).translate(translate: translate);
/// Text format with custom args
static String? textFormat(String? text, List<dynamic> args) =>
TextFormatter(text).format(args);
static String? textFormat(String? text,
{List<dynamic>? args, bool translate = false}) =>
textFormatter(text, translate: translate).format(args: args);
/// Text decorator with custom key/value params
static String? decorator(String? text, Map<String, dynamic> params) =>
TextFormatter(text).decorate(params);
static String? decorator(String? text,
{Map<String, dynamic>? params, bool translate = false}) =>
textFormatter(text, translate: translate).decorate(params: params);
static String? asLowerCaseThenTrim(String? text) =>
text?.toLowerCase().trim();

View File

@ -1,3 +1,5 @@
import 'package:cubetiq/i18n_translator.dart';
/// Text Formatter
///
/// @author sombochea
@ -9,12 +11,20 @@ class TextFormatter {
this.text = text;
}
String? format(List<dynamic> args) {
TextFormatter translate({bool translate = true}) {
if (translate && text != null && text?.isNotEmpty == true) {
text = TranslatorFactory.translate(text!);
}
return this;
}
String? format({List<dynamic>? args}) {
if (text == null) {
return null;
}
if (args.isEmpty) {
if (args == null || args.isEmpty == true) {
return text;
}
@ -31,12 +41,12 @@ class TextFormatter {
return msg;
}
String? decorate(Map<String, dynamic> params) {
String? decorate({Map<String, dynamic>? params}) {
if (text == null) {
return null;
}
if (params.isEmpty) {
if (params == null || params.isEmpty == true) {
return text;
}

View File

@ -8,6 +8,14 @@ class XLog {
logger.success(data, args);
}
static void log(String prefix, dynamic data, [List? args]) {
logger.show(XLogType.DEBUG, prefix, data, args);
}
static void show(XLogType type, String prefix, dynamic data, [List? args]) {
logger.show(type, prefix, data, args);
}
static void info(dynamic data, [List? args]) {
logger.info(data, args);
}

View File

@ -25,7 +25,7 @@ abstract class XLogProvider {
if (args == null || args.isEmpty) {
content = data;
} else {
content = StringUtils.textFormat(data, args) ?? 'null';
content = StringUtils.textFormat(data, args: args) ?? 'null';
}
var text = '[$type] ${nowToString()}: $prefix => $content'.trim();

View File

@ -1,6 +1,6 @@
name: cubetiq
description: CUBETIQ Dart Shared is functions, utils, and extensions for developers.
version: 1.0.0
version: 1.0.1
homepage: https://www.cubetiqs.com
repository: https://git.cubetiqs.com/CUBETIQ/cubetiq_dart_shared.git

View File

@ -0,0 +1,37 @@
import 'package:cubetiq/i18n_translator.dart';
import 'package:cubetiq/src/xlog/xlog.dart';
import 'package:cubetiq/text.dart';
import 'package:test/test.dart';
void main() {
test('test translate function', () {
var text1 = 'Hello, my name is {0}!';
var result1 = TextFormatter(text1).translate().format(args: ['Sambo']);
XLog.success(result1);
expect('Hello, my name is Sambo!', result1);
TranslatorFactory.setProvider(TranslatorProviderExample());
result1 = TextFormatter(text1).translate().format(args: ['Sambo']);
XLog.success(result1);
expect('ឈ្មោះរបស់អ្នកគឺ Sambo!', result1);
});
}
class TranslatorProviderExample implements TranslatorProvider {
@override
bool hasKey(String key) {
return false;
}
@override
String translate(String key,
{Map<String, dynamic>? params, String? fallback}) {
if (key == 'Hello, my name is {0}!') {
return 'ឈ្មោះរបស់អ្នកគឺ {0}!';
}
return key;
}
}

View File

@ -4,10 +4,10 @@ import 'package:test/test.dart';
void main() {
test('text formatter function format', () {
var text1 = 'Hello, {0}!';
var result1 = TextFormatter(text1).format(['Sambo']);
var result1 = TextFormatter(text1).format(args: ['Sambo']);
var text2 = 'Hello, {name}!';
var result2 = TextFormatter(text2).decorate({'name': 'Chea'});
var result2 = TextFormatter(text2).decorate(params: {'name': 'Chea'});
expect('Hello, Sambo!', result1);
expect('Hello, Chea!', result2);