mirror of
https://github.com/openfoodfacts/smooth-app.git
synced 2025-08-26 03:01:45 +08:00
refactor: Rename tagline*
to AppNews
(#5377)
* Rename `tagline*` to `AppNews` * Fix labeler path
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
part of 'tagline_provider.dart';
|
||||
part of 'newsfeed_provider.dart';
|
||||
|
||||
/// Content from the JSON and converted to what's in "tagmodel.dart"
|
||||
/// Content from the JSON and converted to what's in "newsfeed_model.dart"
|
||||
|
||||
class _TagLineJSON {
|
||||
_TagLineJSON.fromJson(Map<dynamic, dynamic> json)
|
||||
@ -15,17 +15,16 @@ class _TagLineJSON {
|
||||
final _TagLineJSONNewsList news;
|
||||
final _TaglineJSONFeed taglineFeed;
|
||||
|
||||
TagLine toTagLine(String locale) {
|
||||
final Map<String, TagLineNewsItem> tagLineNews = news.map(
|
||||
(String key, _TagLineItemNewsItem value) =>
|
||||
MapEntry<String, TagLineNewsItem>(
|
||||
AppNews toTagLine(String locale) {
|
||||
final Map<String, AppNewsItem> tagLineNews = news.map(
|
||||
(String key, _TagLineItemNewsItem value) => MapEntry<String, AppNewsItem>(
|
||||
key,
|
||||
value.toTagLineItem(locale),
|
||||
),
|
||||
);
|
||||
|
||||
final _TagLineJSONFeedLocale localizedFeed = taglineFeed.loadNews(locale);
|
||||
final Iterable<TagLineFeedItem> feed = localizedFeed.news
|
||||
final Iterable<AppNewsFeedItem> feed = localizedFeed.news
|
||||
.map((_TagLineJSONFeedLocaleItem item) {
|
||||
if (news[item.id] == null) {
|
||||
// The asked ID doesn't exist in the news
|
||||
@ -33,16 +32,16 @@ class _TagLineJSON {
|
||||
}
|
||||
return item.overrideNewsItem(news[item.id]!, locale);
|
||||
})
|
||||
.where((TagLineFeedItem? item) =>
|
||||
.where((AppNewsFeedItem? item) =>
|
||||
item != null &&
|
||||
(item.startDate == null ||
|
||||
item.startDate!.isBefore(DateTime.now())) &&
|
||||
(item.endDate == null || item.endDate!.isAfter(DateTime.now())))
|
||||
.whereNotNull();
|
||||
|
||||
return TagLine(
|
||||
news: TagLineNewsList(tagLineNews),
|
||||
feed: TagLineFeed(
|
||||
return AppNews(
|
||||
news: AppNewsList(tagLineNews),
|
||||
feed: AppNewsFeed(
|
||||
feed.toList(growable: false),
|
||||
),
|
||||
);
|
||||
@ -106,10 +105,10 @@ class _TagLineItemNewsItem {
|
||||
return _translations['default']!.merge(translation);
|
||||
}
|
||||
|
||||
TagLineNewsItem toTagLineItem(String locale) {
|
||||
AppNewsItem toTagLineItem(String locale) {
|
||||
final _TagLineItemNewsTranslation translation = loadTranslation(locale);
|
||||
// We can assume the default translation has a non-null title and message
|
||||
return TagLineNewsItem(
|
||||
return AppNewsItem(
|
||||
id: id,
|
||||
title: translation.title!,
|
||||
message: translation.message!,
|
||||
@ -224,8 +223,8 @@ class _TagLineNewsImage {
|
||||
final double? width;
|
||||
final String? alt;
|
||||
|
||||
TagLineImage toTagLineImage() {
|
||||
return TagLineImage(
|
||||
AppNewsImage toTagLineImage() {
|
||||
return AppNewsImage(
|
||||
src: url,
|
||||
width: width,
|
||||
alt: alt,
|
||||
@ -303,7 +302,7 @@ class _TagLineNewsStyle {
|
||||
);
|
||||
}
|
||||
|
||||
TagLineStyle toTagLineStyle() => TagLineStyle.fromHexa(
|
||||
AppNewsStyle toTagLineStyle() => AppNewsStyle.fromHexa(
|
||||
titleBackground: titleBackground,
|
||||
titleTextColor: titleTextColor,
|
||||
titleIndicatorColor: titleIndicatorColor,
|
||||
@ -369,7 +368,7 @@ class _TagLineJSONFeedLocaleItem {
|
||||
final String id;
|
||||
final _TagLineJSONFeedNewsItemOverride? overrideContent;
|
||||
|
||||
TagLineFeedItem overrideNewsItem(
|
||||
AppNewsFeedItem overrideNewsItem(
|
||||
_TagLineItemNewsItem newsItem,
|
||||
String locale,
|
||||
) {
|
||||
@ -384,9 +383,9 @@ class _TagLineJSONFeedLocaleItem {
|
||||
);
|
||||
}
|
||||
|
||||
final TagLineNewsItem tagLineItem = item.toTagLineItem(locale);
|
||||
final AppNewsItem tagLineItem = item.toTagLineItem(locale);
|
||||
|
||||
return TagLineFeedItem(
|
||||
return AppNewsFeedItem(
|
||||
news: tagLineItem,
|
||||
startDate: tagLineItem.startDate,
|
||||
endDate: tagLineItem.endDate,
|
@ -1,35 +1,35 @@
|
||||
import 'dart:ui';
|
||||
|
||||
class TagLine {
|
||||
const TagLine({
|
||||
class AppNews {
|
||||
const AppNews({
|
||||
required this.news,
|
||||
required this.feed,
|
||||
});
|
||||
|
||||
final TagLineNewsList news;
|
||||
final TagLineFeed feed;
|
||||
final AppNewsList news;
|
||||
final AppNewsFeed feed;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLine{news: $news, feed: $feed}';
|
||||
return 'AppNews{news: $news, feed: $feed}';
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineNewsList {
|
||||
const TagLineNewsList(Map<String, TagLineNewsItem> news) : _news = news;
|
||||
class AppNewsList {
|
||||
const AppNewsList(Map<String, AppNewsItem> news) : _news = news;
|
||||
|
||||
final Map<String, TagLineNewsItem> _news;
|
||||
final Map<String, AppNewsItem> _news;
|
||||
|
||||
TagLineNewsItem? operator [](String key) => _news[key];
|
||||
AppNewsItem? operator [](String key) => _news[key];
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLineNewsList{_news: $_news}';
|
||||
return 'AppNewsList{_news: $_news}';
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineNewsItem {
|
||||
const TagLineNewsItem({
|
||||
class AppNewsItem {
|
||||
const AppNewsItem({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.message,
|
||||
@ -48,17 +48,17 @@ class TagLineNewsItem {
|
||||
final String? buttonLabel;
|
||||
final DateTime? startDate;
|
||||
final DateTime? endDate;
|
||||
final TagLineImage? image;
|
||||
final TagLineStyle? style;
|
||||
final AppNewsImage? image;
|
||||
final AppNewsStyle? style;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLineNewsItem{id: $id, title: $title, message: $message, url: $url, buttonLabel: $buttonLabel, startDate: $startDate, endDate: $endDate, image: $image, style: $style}';
|
||||
return 'AppNewsItem{id: $id, title: $title, message: $message, url: $url, buttonLabel: $buttonLabel, startDate: $startDate, endDate: $endDate, image: $image, style: $style}';
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineStyle {
|
||||
const TagLineStyle({
|
||||
class AppNewsStyle {
|
||||
const AppNewsStyle({
|
||||
this.titleBackground,
|
||||
this.titleTextColor,
|
||||
this.titleIndicatorColor,
|
||||
@ -69,7 +69,7 @@ class TagLineStyle {
|
||||
this.contentBackgroundColor,
|
||||
});
|
||||
|
||||
TagLineStyle.fromHexa({
|
||||
AppNewsStyle.fromHexa({
|
||||
String? titleBackground,
|
||||
String? titleTextColor,
|
||||
String? titleIndicatorColor,
|
||||
@ -105,12 +105,12 @@ class TagLineStyle {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLineStyle{titleBackground: $titleBackground, titleTextColor: $titleTextColor, titleIndicatorColor: $titleIndicatorColor, messageBackground: $messageBackground, messageTextColor: $messageTextColor, buttonBackground: $buttonBackground, buttonTextColor: $buttonTextColor, contentBackgroundColor: $contentBackgroundColor}';
|
||||
return 'AppNewsStyle{titleBackground: $titleBackground, titleTextColor: $titleTextColor, titleIndicatorColor: $titleIndicatorColor, messageBackground: $messageBackground, messageTextColor: $messageTextColor, buttonBackground: $buttonBackground, buttonTextColor: $buttonTextColor, contentBackgroundColor: $contentBackgroundColor}';
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineImage {
|
||||
const TagLineImage({
|
||||
class AppNewsImage {
|
||||
const AppNewsImage({
|
||||
required this.src,
|
||||
this.width,
|
||||
this.alt,
|
||||
@ -122,14 +122,14 @@ class TagLineImage {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLineImage{src: $src, width: $width, alt: $alt}';
|
||||
return 'AppNewsImage{src: $src, width: $width, alt: $alt}';
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineFeed {
|
||||
const TagLineFeed(this.news);
|
||||
class AppNewsFeed {
|
||||
const AppNewsFeed(this.news);
|
||||
|
||||
final List<TagLineFeedItem> news;
|
||||
final List<AppNewsFeedItem> news;
|
||||
|
||||
bool get isNotEmpty => news.isNotEmpty;
|
||||
|
||||
@ -139,15 +139,15 @@ class TagLineFeed {
|
||||
}
|
||||
}
|
||||
|
||||
class TagLineFeedItem {
|
||||
const TagLineFeedItem({
|
||||
class AppNewsFeedItem {
|
||||
const AppNewsFeedItem({
|
||||
required this.news,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) : _startDate = startDate,
|
||||
_endDate = endDate;
|
||||
|
||||
final TagLineNewsItem news;
|
||||
final AppNewsItem news;
|
||||
final DateTime? _startDate;
|
||||
final DateTime? _endDate;
|
||||
|
||||
@ -159,6 +159,6 @@ class TagLineFeedItem {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TagLineFeedItem{news: $news, _startDate: $_startDate, _endDate: $_endDate}';
|
||||
return 'AppNewsFeedItem{news: $news, _startDate: $_startDate, _endDate: $_endDate}';
|
||||
}
|
||||
}
|
@ -8,23 +8,23 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:openfoodfacts/openfoodfacts.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:smooth_app/data_models/news_feed/newsfeed_model.dart';
|
||||
import 'package:smooth_app/data_models/preferences/user_preferences.dart';
|
||||
import 'package:smooth_app/data_models/tagline/tagline_model.dart';
|
||||
import 'package:smooth_app/pages/preferences/user_preferences_dev_mode.dart';
|
||||
import 'package:smooth_app/query/product_query.dart';
|
||||
import 'package:smooth_app/services/smooth_services.dart';
|
||||
|
||||
part 'tagline_json.dart';
|
||||
part 'newsfeed_json.dart';
|
||||
|
||||
/// The TagLine provides one one side a list of news and on the other a feed
|
||||
/// containing the some of the news
|
||||
/// This provides one one side a list of news and on the other a feed of news.
|
||||
/// A feed contains some of the news?
|
||||
///
|
||||
/// The TagLine is fetched on the server and cached locally (1 day).
|
||||
/// The content is fetched on the server and cached locally (1 day).
|
||||
/// To be notified of changes, listen to this [ChangeNotifier] and more
|
||||
/// particularly to the [state] property
|
||||
class TagLineProvider extends ChangeNotifier {
|
||||
TagLineProvider(UserPreferences preferences)
|
||||
: _state = const TagLineLoading(),
|
||||
/// particularly to the [state] property.
|
||||
class AppNewsProvider extends ChangeNotifier {
|
||||
AppNewsProvider(UserPreferences preferences)
|
||||
: _state = const AppNewsStateLoading(),
|
||||
_preferences = preferences,
|
||||
_domain = preferences.getDevModeString(
|
||||
UserPreferencesDevMode.userPreferencesTestEnvDomain) ??
|
||||
@ -33,17 +33,17 @@ class TagLineProvider extends ChangeNotifier {
|
||||
.getFlag(UserPreferencesDevMode.userPreferencesFlagProd) ??
|
||||
true {
|
||||
_preferences.addListener(_onPreferencesChanged);
|
||||
loadTagLine();
|
||||
loadLatestNews();
|
||||
}
|
||||
|
||||
final UserPreferences _preferences;
|
||||
|
||||
TagLineState _state;
|
||||
AppNewsState _state;
|
||||
|
||||
bool get hasContent => _state is TagLineLoaded;
|
||||
bool get hasContent => _state is AppNewsStateLoaded;
|
||||
|
||||
Future<void> loadTagLine({bool forceUpdate = false}) async {
|
||||
_emit(const TagLineLoading());
|
||||
Future<void> loadLatestNews({bool forceUpdate = false}) async {
|
||||
_emit(const AppNewsStateLoading());
|
||||
|
||||
final String locale = ProductQuery.getLocaleString();
|
||||
if (locale.startsWith('-')) {
|
||||
@ -51,43 +51,43 @@ class TagLineProvider extends ChangeNotifier {
|
||||
return;
|
||||
}
|
||||
|
||||
final File cacheFile = await _tagLineCacheFile;
|
||||
final File cacheFile = await _newsCacheFile;
|
||||
String? jsonString;
|
||||
// Try from the cache first
|
||||
if (!forceUpdate && _isTagLineCacheValid(cacheFile)) {
|
||||
if (!forceUpdate && _isNewsCacheValid(cacheFile)) {
|
||||
jsonString = cacheFile.readAsStringSync();
|
||||
}
|
||||
|
||||
if (jsonString == null || jsonString.isEmpty == true) {
|
||||
jsonString = await _fetchTagLine();
|
||||
jsonString = await _fetchJSON();
|
||||
}
|
||||
|
||||
if (jsonString?.isNotEmpty != true) {
|
||||
_emit(const TagLineError('JSON file is empty'));
|
||||
_emit(const AppNewsStateError('JSON news file is empty'));
|
||||
return;
|
||||
}
|
||||
|
||||
final TagLine? tagLine = await Isolate.run(
|
||||
final AppNews? tagLine = await Isolate.run(
|
||||
() => _parseJSONAndGetLocalizedContent(jsonString!, locale));
|
||||
if (tagLine == null) {
|
||||
_emit(const TagLineError('Unable to parse the JSON file'));
|
||||
Logs.e('Unable to parse the Tagline file');
|
||||
_emit(const AppNewsStateError('Unable to parse the JSON news file'));
|
||||
Logs.e('Unable to parse the JSON news file');
|
||||
} else {
|
||||
_emit(TagLineLoaded(tagLine));
|
||||
Logs.i('TagLine reloaded');
|
||||
_emit(AppNewsStateLoaded(tagLine));
|
||||
Logs.i('News ${forceUpdate ? 're' : ''}loaded');
|
||||
}
|
||||
}
|
||||
|
||||
void _emit(TagLineState state) {
|
||||
void _emit(AppNewsState state) {
|
||||
_state = state;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
|
||||
TagLineState get state => _state;
|
||||
AppNewsState get state => _state;
|
||||
|
||||
static Future<TagLine?> _parseJSONAndGetLocalizedContent(
|
||||
static Future<AppNews?> _parseJSONAndGetLocalizedContent(
|
||||
String json,
|
||||
String locale,
|
||||
) async {
|
||||
@ -102,11 +102,11 @@ class TagLineProvider extends ChangeNotifier {
|
||||
|
||||
/// API URL: [https://world.openfoodfacts.[org/net]/resources/files/tagline-off-ios-v3.json]
|
||||
/// or [https://world.openfoodfacts.[org/net]/resources/files/tagline-off-android-v3.json]
|
||||
Future<String?> _fetchTagLine() async {
|
||||
Future<String?> _fetchJSON() async {
|
||||
try {
|
||||
final UriProductHelper uriProductHelper = ProductQuery.uriProductHelper;
|
||||
final Map<String, String> headers = <String, String>{};
|
||||
final Uri uri = uriProductHelper.getUri(path: _tagLineUrl);
|
||||
final Uri uri = uriProductHelper.getUri(path: _newsUrl);
|
||||
|
||||
if (uriProductHelper.userInfoForPatch != null) {
|
||||
headers['Authorization'] =
|
||||
@ -125,7 +125,7 @@ class TagLineProvider extends ChangeNotifier {
|
||||
if (!json.startsWith('[') && !json.startsWith('{')) {
|
||||
throw Exception('Invalid JSON');
|
||||
}
|
||||
await _saveTagLineToCache(json);
|
||||
await _saveNewsToCache(json);
|
||||
return json;
|
||||
} catch (_) {
|
||||
return null;
|
||||
@ -133,7 +133,7 @@ class TagLineProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
/// Based on the platform, the URL may differ
|
||||
String get _tagLineUrl {
|
||||
String get _newsUrl {
|
||||
if (Platform.isIOS || Platform.isMacOS) {
|
||||
return '/resources/files/tagline-off-ios-v3.json';
|
||||
} else {
|
||||
@ -141,15 +141,15 @@ class TagLineProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<File> get _tagLineCacheFile => getApplicationCacheDirectory()
|
||||
Future<File> get _newsCacheFile => getApplicationCacheDirectory()
|
||||
.then((Directory dir) => File(join(dir.path, 'tagline.json')));
|
||||
|
||||
Future<File> _saveTagLineToCache(final String json) async {
|
||||
final File file = await _tagLineCacheFile;
|
||||
Future<File> _saveNewsToCache(final String json) async {
|
||||
final File file = await _newsCacheFile;
|
||||
return file.writeAsString(json);
|
||||
}
|
||||
|
||||
bool _isTagLineCacheValid(File file) =>
|
||||
bool _isNewsCacheValid(File file) =>
|
||||
file.existsSync() &&
|
||||
file.lengthSync() > 0 &&
|
||||
file
|
||||
@ -172,7 +172,7 @@ class TagLineProvider extends ChangeNotifier {
|
||||
if (domain != _domain || prodEnv != _prodEnv) {
|
||||
_domain = domain;
|
||||
_prodEnv = prodEnv;
|
||||
loadTagLine(forceUpdate: true);
|
||||
loadLatestNews(forceUpdate: true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,22 +183,22 @@ class TagLineProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TagLineState {
|
||||
const TagLineState();
|
||||
sealed class AppNewsState {
|
||||
const AppNewsState();
|
||||
}
|
||||
|
||||
final class TagLineLoading extends TagLineState {
|
||||
const TagLineLoading();
|
||||
final class AppNewsStateLoading extends AppNewsState {
|
||||
const AppNewsStateLoading();
|
||||
}
|
||||
|
||||
class TagLineLoaded extends TagLineState {
|
||||
const TagLineLoaded(this.tagLineContent);
|
||||
class AppNewsStateLoaded extends AppNewsState {
|
||||
const AppNewsStateLoaded(this.tagLineContent);
|
||||
|
||||
final TagLine tagLineContent;
|
||||
final AppNews tagLineContent;
|
||||
}
|
||||
|
||||
class TagLineError extends TagLineState {
|
||||
const TagLineError(this.exception);
|
||||
class AppNewsStateError extends AppNewsState {
|
||||
const AppNewsStateError(this.exception);
|
||||
|
||||
final dynamic exception;
|
||||
}
|
Reference in New Issue
Block a user