Skip to content
This repository was archived by the owner on May 25, 2025. It is now read-only.

Commit f485f4e

Browse files
committed
docs: initial documentation for repository
- Added overview of the package - Described features and usage - Included error handling details
1 parent 8a838ef commit f485f4e

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

README.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# ht_preferences_repository
2+
3+
![coverage: percentage](https://img.shields.io/badge/coverage-92-green)
4+
[![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis)
5+
[![License: PolyForm Free Trial](https://img.shields.io/badge/License-PolyForm%20Free%20Trial-blue)](https://polyformproject.org/licenses/free-trial/1.0.0)
6+
7+
Repository for managing user preferences. This repository acts as an intermediary between the application's business logic (BLoCs) and the data source client (`HtPreferencesClient`). It handles potential client-level exceptions and enforces additional business rules, such as limiting the size of the headline reading history.
8+
9+
## Overview
10+
11+
This package provides a `HtPreferencesRepository` class designed to abstract the storage and retrieval of user preferences within a Flutter application. It sits on top of a `HtPreferencesClient` implementation (which handles the actual data persistence, e.g., using Firestore, local storage, etc.) and provides a clean, consistent API for managing various user settings and data.
12+
13+
## Features
14+
15+
* **Settings Management:** Get and set application, article, theme, feed, and notification settings.
16+
* **Bookmark Management:** Add, remove, and retrieve bookmarked headlines.
17+
* **Followed Items:** Manage lists of followed sources, categories, and event countries.
18+
* **Reading History:** Track headline reading history, automatically managing its size (defaults to 25 items).
19+
* **Error Handling:** Propagates specific exceptions (`PreferenceNotFoundException`, `PreferenceUpdateException`) from the client and wraps unexpected errors.
20+
* **Client Agnostic:** Works with any implementation of the `HtPreferencesClient` interface.
21+
22+
## Getting Started
23+
24+
Add the necessary packages to your `pubspec.yaml` file under dependencies:
25+
26+
```yaml
27+
dependencies:
28+
flutter:
29+
sdk: flutter
30+
# This repository package
31+
ht_preferences_repository:
32+
git:
33+
url: https://github.com/headlines-toolkit/ht-preferences-repository.git
34+
# Optionally specify a ref (branch, tag, commit hash):
35+
# ref: main
36+
37+
# The client interface (required by the repository)
38+
ht_preferences_client:
39+
git:
40+
url: https://github.com/headlines-toolkit/ht-preferences-client.git
41+
# ref: main
42+
43+
# A client implementation (e.g., Firestore)
44+
ht_preferences_firestore:
45+
git:
46+
url: https://github.com/headlines-toolkit/ht-preferences-firestore.git
47+
# ref: main
48+
49+
# Other dependencies your client might need (e.g., cloud_firestore)
50+
cloud_firestore: ^4.0.0 # Example version
51+
```
52+
53+
Then run `flutter pub get`.
54+
55+
## Usage
56+
57+
Import the necessary packages and instantiate the repository with your chosen `HtPreferencesClient` implementation (e.g., `HtPreferencesFirestore`). You'll typically do this where you provide dependencies to your application (like in `main.dart` or using a dependency injection framework).
58+
59+
```dart
60+
import 'package:flutter/material.dart'; // For ThemeMode example
61+
import 'package:cloud_firestore/cloud_firestore.dart'; // Firestore dependency
62+
import 'package:ht_preferences_client/ht_preferences_client.dart';
63+
import 'package:ht_preferences_repository/ht_preferences_repository.dart';
64+
import 'package:ht_preferences_firestore/ht_preferences_firestore.dart'; // Import the client implementation
65+
66+
// Assume firestoreInstance and userId are available in your app context
67+
// FirebaseFirestore firestoreInstance = FirebaseFirestore.instance;
68+
// String userId = 'some_user_id';
69+
70+
void main() async {
71+
// --- Dependency Setup (Example) ---
72+
// In a real app, initialize Firebase, get user ID, etc.
73+
WidgetsFlutterBinding.ensureInitialized();
74+
// await Firebase.initializeApp(...);
75+
final firestoreInstance = FirebaseFirestore.instance; // Replace with your actual instance
76+
const userId = 'test_user_123'; // Replace with actual user ID
77+
78+
// Instantiate the Firestore client
79+
final preferencesClient = HtPreferencesFirestore(
80+
firestore: firestoreInstance,
81+
userId: userId,
82+
);
83+
84+
// Create the repository instance, injecting the client
85+
final preferencesRepository = HtPreferencesRepository(
86+
preferencesClient: preferencesClient,
87+
maxHistorySize: 50, // Optionally override default history size (25)
88+
);
89+
// --- End Dependency Setup ---
90+
91+
92+
// --- Using the Repository ---
93+
try {
94+
// --- Settings ---
95+
// Get current app settings
96+
AppSettings currentAppSettings = await preferencesRepository.getAppSettings();
97+
print('Current App Font Size: ${currentAppSettings.appFontSize}');
98+
print('Current App Font Type: ${currentAppSettings.appFontType}');
99+
100+
// Update app settings
101+
final newAppSettings = AppSettings(
102+
appFontSize: FontSize.large,
103+
appFontType: AppFontType.lato,
104+
);
105+
await preferencesRepository.setAppSettings(newAppSettings);
106+
print('App settings updated.');
107+
108+
// Get theme settings
109+
ThemeSettings currentThemeSettings = await preferencesRepository.getThemeSettings();
110+
print('Current Theme Mode: ${currentThemeSettings.themeMode}');
111+
112+
// Update theme settings
113+
final newThemeSettings = ThemeSettings(
114+
themeMode: AppThemeMode.dark, // Use enum from ht_preferences_client
115+
themeName: AppThemeName.blue, // Use enum from ht_preferences_client
116+
);
117+
await preferencesRepository.setThemeSettings(newThemeSettings);
118+
print('Theme settings updated.');
119+
120+
// --- Bookmarks ---
121+
final headline1 = Headline(id: 'h1', title: 'Example Headline 1', description: 'Desc 1');
122+
final headline2 = Headline(id: 'h2', title: 'Example Headline 2', url: 'http://example.com');
123+
124+
await preferencesRepository.addBookmarkedHeadline(headline1);
125+
print('Headline 1 bookmarked.');
126+
await preferencesRepository.addBookmarkedHeadline(headline2);
127+
print('Headline 2 bookmarked.');
128+
129+
List<Headline> bookmarks = await preferencesRepository.getBookmarkedHeadlines();
130+
print('Current Bookmarks (${bookmarks.length}): ${bookmarks.map((h) => h.title).toList()}');
131+
132+
await preferencesRepository.removeBookmarkedHeadline('h1');
133+
print('Headline 1 removed from bookmarks.');
134+
bookmarks = await preferencesRepository.getBookmarkedHeadlines();
135+
print('Updated Bookmarks (${bookmarks.length}): ${bookmarks.map((h) => h.title).toList()}');
136+
137+
// --- Followed Items ---
138+
final categoryTech = Category(id: 'cat-tech', name: 'Technology');
139+
final categorySports = Category(id: 'cat-sports', name: 'Sports');
140+
await preferencesRepository.setFollowedCategories([categoryTech, categorySports]);
141+
print('Followed categories set.');
142+
143+
List<Category> followedCategories = await preferencesRepository.getFollowedCategories();
144+
print('Followed Categories: ${followedCategories.map((c) => c.name).toList()}');
145+
146+
// --- History ---
147+
final headline3 = Headline(id: 'h3', title: 'History Headline 3');
148+
await preferencesRepository.addHeadlineToHistory(headline1); // Add h1 back for history
149+
await preferencesRepository.addHeadlineToHistory(headline2);
150+
await preferencesRepository.addHeadlineToHistory(headline3);
151+
print('Headlines added to history.');
152+
153+
List<Headline> history = await preferencesRepository.getHeadlineReadingHistory();
154+
print('Current History (${history.length} items): ${history.map((h) => h.title).toList()}');
155+
156+
// Adding more items might prune the history based on maxHistorySize
157+
for (int i = 4; i < 60; i++) {
158+
await preferencesRepository.addHeadlineToHistory(Headline(id: 'h$i', title: 'History Headline $i'));
159+
}
160+
history = await preferencesRepository.getHeadlineReadingHistory();
161+
print('History after adding more (${history.length} items - potentially pruned): ${history.map((h) => h.title).toList()}');
162+
163+
await preferencesRepository.removeHeadlineToHistory('h2');
164+
print('Headline 2 removed from history.');
165+
history = await preferencesRepository.getHeadlineReadingHistory();
166+
print('Updated History (${history.length} items): ${history.map((h) => h.title).toList()}');
167+
168+
169+
} on PreferenceNotFoundException catch (e) {
170+
// Handle cases where settings/data haven't been set yet
171+
print('Error: Preference not found - ${e.message}');
172+
} on PreferenceUpdateException catch (e) {
173+
// Handle errors during data fetching/saving
174+
print('Error: Failed to update preference - ${e.message}');
175+
} catch (e) {
176+
print('An unexpected error occurred: $e');
177+
}
178+
}
179+
```
180+
181+
## Error Handling
182+
183+
The repository methods may throw the following exceptions originating from the `ht_preferences_client`:
184+
185+
* `PreferenceNotFoundException`: Thrown when a requested preference or data item (like settings or history) cannot be found.
186+
* `PreferenceUpdateException`: Thrown when an operation to fetch or update a preference fails (e.g., network error, database error).
187+
188+
It's recommended to wrap calls to the repository methods in `try-catch` blocks to handle these potential errors gracefully in your application's business logic layer (e.g., BLoCs).
189+
190+
## Dependencies
191+
192+
* **ht_preferences_client:** This package relies heavily on the `ht_preferences_client` interface package, which defines the contract for interacting with the underlying preference data source. You will need to provide an implementation of `HtPreferencesClient` when creating the `HtPreferencesRepository`.
193+
194+
## License
195+
196+
This package is licensed under the [PolyForm Free Trial License 1.0.0](LICENSE). See the [LICENSE](LICENSE) file for details.

0 commit comments

Comments
 (0)