Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thanhtunguet/truesight_flutter
TrueSight Flutter
https://github.com/thanhtunguet/truesight_flutter
Last synced: 23 days ago
JSON representation
TrueSight Flutter
- Host: GitHub
- URL: https://github.com/thanhtunguet/truesight_flutter
- Owner: thanhtunguet
- License: bsd-3-clause
- Created: 2023-03-22T02:45:41.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-05-28T07:25:32.000Z (7 months ago)
- Last Synced: 2024-05-28T14:47:26.310Z (7 months ago)
- Language: Dart
- Size: 493 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# truesight_flutter
_Core library for TrueSight team's Flutter applications._
- [Introduction](#introduction)
- [Getting Started](#getting-started)
- [Installation](#installation)
- [Usage](#usage)
- [Widget Documentation](#widget-documentation)
- [Custom Image Provider](#custom-image-provider)
- [Cookie Management](#cookie-management)
- [Date and Time Formats](#date-and-time-formats)
- [Additional Information](#additional-information)## Getting Started
To install this package, run:
```sh
flutter pub add truesight_flutter go_router intl
```### Dependencies
This package depends on some libraries that must be installed manually:
```yaml
dependencies:
# ...others
carbon_icons:
git: https://github.com/thanhtunguet/carbon-icons.git
```## Usage
### JSON Serialization
The library provides the following classes:
- `DataModel`: Represents an entity in the application, typically mapped to a table in the backend database.
- `DataFilter`: Filter set for a specific `DataModel`.Convention: Each `DataModel` should have a corresponding `DataFilter`.
Entities and filters in the application should extend these two classes.
To define a new class, consider the following example with the `AppUser` class:
```dart
class AppUser extends DataModel {
@override
List get fields => [
username,
password,
email,
isAdmin,
dateOfBirth,
age,
level,
manager,
members,
];JsonString username = JsonString('username', isRequired: false, helper: 'Username of the user');
JsonString password = JsonString('password', isRequired: false, helper: 'Password of the user');
JsonString email = JsonString('email', isRequired: false, helper: 'Email of the user');
JsonBoolean isAdmin = JsonBoolean('isAdmin', isRequired: false, helper: 'Is the user an admin');
JsonDate dateOfBirth = JsonDate('dateOfBirth', isRequired: false, helper: 'User\'s date of birth');
JsonInteger age = JsonInteger('age', isRequired: false, helper: 'Age of the user');
JsonDouble level = JsonDouble('level', isRequired: false, helper: 'Level of the user');
JsonObject manager = JsonObject('manager', isRequired: false, helper: 'Manager of the user');
JsonList members = JsonList('members', isRequired: false, helper: 'Members that this user manages');
}
```Explanation:
- `fields` getter: These are the JSON fields that will be automatically mapped from JSON when fetching data from the backend.
- JSON data fields are represented by the following classes:| Class | Dart Data Type |
|---------------|-------------------|
| `JsonDate` | `DateTime` |
| `JsonBoolean` | `bool` |
| `JsonString` | `String` |
| `JsonInteger` | `int` |
| `JsonDouble` | `double` |
| `JsonNumber` | `num` |
| `JsonObject` | `DataModel` |
| `JsonList` | `List` |The `JsonXYZ` classes inherit from `JsonField`.
#### Mapping Data from JSON
```dart
final json = await requestFromAPI();
AppUser user = AppUser();
user.fromJSON(json);
```#### Converting to JSON
```dart
AppUser user = AppUser();
user.toJSON(); // Returns the JSON representation of the user, typically a Dart Map object.
user.toString(); // Returns the JSON representation of the user as a Dart String.
```### Advanced Filters
Similar to JSON classes, the library defines `FilterField` data types as follows:
| Class | Dart Data Type | JSON Data Type |
|----------------|----------------|----------------|
| `StringFilter` | `String` | `JsonString` |
| `DateFilter` | `DateTime` | `JsonDate` |
| `GuidFilter` | `String` | `JsonString` |
| `IdFilter` | `int` | `JsonInteger` |
| `IntFilter` | `int` | `JsonInteger` |
| `DoubleFilter` | `double` | `JsonDouble` |
| `NumberFilter` | `num` | `JsonNumber` |### HTTP Requests
The repository class performs API calls to the backend to fetch data.
Each `HttpRepository` class can represent a set of APIs corresponding to a specific business logic, such as user login (`UserRepository`) or product management (`ProductRepository`).
The `HttpRepository` class can be used with the `@singleton` annotation from the `injectable` package combined with `get_it` for dependency injection.
Each method in `HttpRepository` corresponds to a specific API.
```dart
@singleton
class UserRepository extends HttpRepository {
@override
InterceptorsWrapper interceptorWrapper = InterceptorsWrapper();@override
String? get baseUrl => 'https://app.example.com';Future login(String username, String password) {
return post("/login", data: {
'username': username,
'password': password,
})
.then((response) => response.body(AppUser));
}
}
```### TrueSightService
The `TrueSightService` is a singleton class designed to handle application-wide settings and configuration management using Hive for local storage and dotenv for environment variable management. This service provides a way to initialize necessary configurations and manage settings like `faceIdEnabled` and `baseApiUrl`.
#### Initialization
##### `initialize`
Initializes the service with optional parameters to enable dotenv and Hive.
###### Parameters
- `enableDotenv` (bool): If `true`, loads environment variables using the `flutter_dotenv` package. Default is `true`.
- `enableHive` (bool): If `true`, initializes Hive and opens a box for storage. Default is `true`.###### Usage
```dart
await truesightService.initialize(
enableDotenv: true,
enableHive: true,
);
```#### Properties
##### `faceIdEnabled`
Getter and setter for the `faceIdEnabled` setting. This setting controls whether Face ID is enabled in the application.
###### Getter
Returns a `bool` indicating whether Face ID is enabled. If the value is not set, it defaults to `true`.###### Setter
Sets the `faceIdEnabled` value.###### Usage
```dart
// Get faceIdEnabled
bool isFaceIdEnabled = truesightService.faceIdEnabled;// Set faceIdEnabled
truesightService.faceIdEnabled = false;
```##### `baseApiUrl`
Getter and setter for the `baseApiUrl` setting. This setting holds the base URL for the API. If the value is not set, it falls back to the environment variable `BASE_API_URL`.
###### Getter
Returns a `String` containing the base API URL. If the value is not set in Hive, it retrieves the value from the environment variables.###### Setter
Sets the `baseApiUrl` value.###### Usage
```dart
// Get baseApiUrl
String apiUrl = truesightService.baseApiUrl;// Set baseApiUrl
truesightService.baseApiUrl = 'https://api.example.com';
```#### Private Methods
##### `_getOrCreate`
A utility method to retrieve a value from Hive or create it with a default value if it does not exist.
###### Parameters
- `key` (String): The key for the value in Hive.
- `defaultValue` (dynamic): The default value to use if the key does not exist.###### Returns
- The value associated with the key, or the default value if the key does not exist.#### Example
Here's an example of how to use the `TrueSightService` in a Flutter application:
```dart
import 'package:flutter/material.dart';
import 'path_to_your_service/truesight_app_service.dart';void main() async {
WidgetsFlutterBinding.ensureInitialized();
await truesightService.initialize();runApp(MyApp());
}class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Truesight App Service Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Face ID Enabled: ${truesightService.faceIdEnabled}'),
Text('Base API URL: ${truesightService.baseApiUrl}'),
ElevatedButton(
onPressed: () {
truesightService.faceIdEnabled = !truesightService.faceIdEnabled;
},
child: Text('Toggle Face ID'),
),
ElevatedButton(
onPressed: () {
truesightService.baseApiUrl = 'https://newapi.example.com';
},
child: Text('Set New API URL'),
),
],
),
),
),
);
}
}
```## Custom Image Provider
A custom image provider designed to fetch images with appended authentication tokens from the server.
### Overview
The `TrueSightImageProvider` class extends `ImageProvider` and modifies image loading behavior to include authentication tokens fetched from cookies.
### Constructor
```dart
TrueSightImageProvider(String url)
```Constructs an instance of `TrueSightImageProvider` with the provided image URL.
### Methods
- **obtainKey(ImageConfiguration configuration)**: Asynchronously obtains a key for the image. Appends authentication token to the URL's query parameters.
- **loadImage(Uri key, ImageDecoderCallback decode)**: Loads the image from the specified URL with authentication headers using an HTTP client. Tracks loading progress with chunk events.### Example Usage
```dart
import 'package:flutter/material.dart';class MyImageWidget extends StatelessWidget {
final String imageUrl = 'https://example.com/image.jpg';@override
Widget build(BuildContext context) {
final imageProvider = TrueSightImageProvider(imageUrl);return Image(
image: imageProvider,
fit: BoxFit.cover,
);
}
}
```In this example, `TrueSightImageProvider` is used as the image provider for an `Image` widget, ensuring the image is fetched with proper authentication.
## Widget Documentation
- [AppNavigationBar](docs/app_navigation_bar.md)
- [AppTitle](docs/app_title.md)
- [BodyText](docs/body_text.md)
- [CarbonButton](docs/carbon_button.md)
- [ConfirmationDialog](docs/confirmation_dialog.md)
- [EllipsisText](docs/ellipsis_text.md)
- [GoBackButton](docs/go_back_button.md)
- [IconPlaceholder](docs/icon_placeholder.md)
- [ImagePlaceholder](docs/image_placeholder.md)
- [SignInButton](docs/sign_in_button.md)
- [SimpleInfiniteList](docs/simple_infinite_list.md)
- [StatefulTextFormField](docs/stateful_text_form_field.md)## Cookie Management
In our app, cookies are managed to handle user sessions and authentication tokens efficiently. The cookies are stored using the `SharedPreferences` package, which allows for persistent storage of key-value pairs on the device.
### Overview
Cookies are essential for maintaining user sessions and handling authentication. The following extension methods and functions facilitate the storage, retrieval, and clearing of cookies in the app.
### Storing Cookies
Cookies are parsed from the `Set-Cookie` header and stored with a prefix in the `SharedPreferences`. The `parseSetCookie` function handles this parsing:
```dart
Map parseSetCookie(String setCookieString) {
Map cookies = {};
List parts = setCookieString.split('; ');
if (parts.isNotEmpty && parts[0].contains('=')) {
List keyValue = parts[0].split('=');
if (keyValue.length == 2) {
cookies[_getCookieKey(keyValue[0])] = keyValue[1];
}
}
return cookies;
}
```### Retrieving Cookies
Cookies are retrieved from the `SharedPreferences` using the `getCookies` function. This function retrieves all keys with the specified prefix and constructs a map of cookies:
```dart
Future> getCookies() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final Set keys = prefs.getKeys();
final Map prefsMap = {};for (String key in keys) {
if (_isCookieKey(key)) {
prefsMap[_getCookieKeyReversed(key)] = prefs.get(key);
}
}return prefsMap;
}
```### Clearing Cookies
Cookies can be cleared from the `SharedPreferences` using the `clearCookies` function. This function removes all keys with the specified prefix:
```dart
Future clearCookies() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final Set keys = prefs.getKeys();for (String key in keys) {
if (_isCookieKey(key)) {
prefs.remove(key);
}
}
}
```### Cookie Extension Methods
The extension methods on `Map` provide easy access to specific cookies, such as `token` and `refreshToken`:
```dart
extension TrueSightCookies on Map {
String? get token => this['Token'];
String? get refreshToken => this['RefreshToken'];
bool get hasToken => this['Token'] != null;
bool get hasRefreshToken => this['RefreshToken'] != null;
}
```These methods simplify the retrieval and usage of cookies in various parts of the app.
### Example Usage
Here is an example of how to use the cookie management functions in your app:
```dart
// Parsing and storing a Set-Cookie header
String setCookieHeader = 'Token=abc123; Path=/; HttpOnly';
Map cookies = parseSetCookie(setCookieHeader);
// Store the parsed cookies using SharedPreferences
// ...// Retrieving stored cookies
Future printStoredCookies() async {
Map cookies = await getCookies();
print('Stored Token: ${cookies.token}');
}// Clearing stored cookies
Future clearStoredCookies() async {
await clearCookies();
print('Cookies cleared');
}
```With these functions and extensions, managing cookies in your app becomes straightforward and efficient.
## Date and Time Formats
Our app uses various date and time formats to ensure consistency and readability, especially tailored for the Vietnamese locale. The formats are defined in the `DateTimeFormatsVN` class and can be easily used throughout the app.
### Available Formats
The `DateTimeFormatsVN` class defines several common date and time formats:
- **Full Date and Time**: `dd/MM/yyyy HH:mm:ss`
- Example: `01/01/2024 14:30:45`
- **Date and Time without Seconds**: `dd/MM/yyyy HH:mm`
- Example: `01/01/2024 14:30`
- **Date Only**: `dd/MM/yyyy`
- Example: `01/01/2024`
- **Time Only**: `HH:mm:ss`
- Example: `14:30:45`
- **Day and Month Only**: `dd/MM`
- Example: `01/01`
- **Year Only**: `yyyy`
- Example: `2024`
- **Date with Day Name**: `EEEE, dd/MM/yyyy`
- Example: `Thứ Hai, 01/01/2024`
- **Date with Month Name**: `dd MMMM yyyy`
- Example: `01 Tháng Giêng 2024`
- **Short Date with Month Name**: `dd MMM`
- Example: `01 Thg 01`### Formatting Dates
The `DateTimeFormatsVN` class includes a helper function to format `DateTime` objects using the specified formats:
```dart
static String format(DateTime dateTime, String format) {
return DateFormat(format, 'vi').format(dateTime);
}
```You can use this function to format dates according to the predefined formats. For example:
```dart
DateTime now = DateTime.now();
String formattedDate = DateTimeFormatsVN.format(now, DateTimeFormatsVN.dateTime);
print(formattedDate); // Output: 01/01/2024 14:30:45
```### Extension Method for DateTime
We have also provided an extension method on the `DateTime` class to simplify the formatting process. This method uses a default format but allows for customization:
```dart
extension DateTimeFormatter on DateTime {
String format({
String dateFormat = DateTimeFormatsVN.dateOnly,
}) {
return DateFormat(dateFormat).format(toLocal());
}
}
```Example usage of the extension method:
```dart
DateTime now = DateTime.now();
String formattedDate = now.format();
print(formattedDate); // Output: 01/01/2024String customFormattedDate = now.format(dateFormat: DateTimeFormatsVN.dateWithDayName);
print(customFormattedDate); // Output: Thứ Hai, 01/01/2024
```### Summary
By using the `DateTimeFormatsVN` class and the `DateTimeFormatter` extension, you can easily format dates and times in your app, ensuring consistency and localization for Vietnamese users.
## Additional Information
This package is under development. Feel free to create an issue.