Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #231 from blazern/news-feed1
Browse files Browse the repository at this point in the history
Create NewsFeedManager, NewsPiece, blank NewsFeedPage and a few other things
  • Loading branch information
blazern authored Mar 22, 2022
2 parents 520491f + 9120286 commit 42ec497
Show file tree
Hide file tree
Showing 24 changed files with 1,603 additions and 325 deletions.
10 changes: 10 additions & 0 deletions assets/bottom_bar_news_feed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion lib/base/build_value_helper.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:plante/contributions/user_contribution.dart';
Expand All @@ -16,6 +17,9 @@ import 'package:plante/outside/backend/backend_product.dart';
import 'package:plante/outside/backend/backend_products_at_shop.dart';
import 'package:plante/outside/backend/backend_shop.dart';
import 'package:plante/outside/backend/mobile_app_config.dart';
import 'package:plante/outside/backend/news/news_data_response.dart';
import 'package:plante/outside/backend/news/news_piece.dart';
import 'package:plante/outside/backend/news/news_piece_product_at_shop.dart';
import 'package:plante/outside/backend/shops_in_bounds_response.dart';
import 'package:plante/outside/map/osm/osm_address.dart';
import 'package:plante/outside/map/osm/osm_road.dart';
Expand Down Expand Up @@ -48,13 +52,20 @@ part 'build_value_helper.g.dart';
UserLangs,
ShopsInBoundsResponse,
UserContribution,
NewsPiece,
NewsPiece,
NewsPieceProductAtShop,
NewsDataResponse,
])
final Serializers _serializers = _$_serializers;
final _jsonSerializers = (_serializers.toBuilder()
..add(OsmUIDBuildValueSerializer())
..addPlugin(StandardJsonPlugin())
..addBuilderFactory(const FullType(BuiltList, [FullType(Ingredient)]),
() => ListBuilder<Ingredient>()))
() => ListBuilder<Ingredient>())
..addBuilderFactory(
const FullType(BuiltMap, [FullType(String), FullType(JsonObject)]),
() => MapBuilder<String, JsonObject>()))
.build();

class BuildValueHelper {
Expand Down
12 changes: 11 additions & 1 deletion lib/base/build_value_helper.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion lib/model/coord.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import 'package:plante/model/coords_bounds.dart';
/// Very similar to the LatLng class from Google libs,
/// **BUT** tails are being cut to certain precision - [lat] and [lon] will
/// have up to [precision] digits after the dot.
/// **AND** if the cut tail is 9 in period (999..), the value is rounded to the
/// next integer (e.g. 1.999 => 2.000).
///
/// Also, this class has some additional methods.
@immutable
Expand All @@ -26,7 +28,18 @@ class Coord {
final scaledBack = rounded / factor;
// scaledBack=1.23400
// 1.23456=>1.23400
return scaledBack;

final minWithGivenPrecision = (1 / factor) * scaledBack.sign;
// =0.001
final scaledBackPlusMin = scaledBack + minWithGivenPrecision;
// 1.23400=>1.23500
if (scaledBackPlusMin.toInt() != scaledBack.toInt()) {
// if scaledBack=1.999, scaledBackPlusMin would be 2.000
return scaledBackPlusMin;
} else {
// if scaledBack=1.998, scaledBackPlusMin would be 1.999
return scaledBack;
}
}

/// Creates a geographical location specified in degrees [lat] and
Expand Down
24 changes: 24 additions & 0 deletions lib/outside/backend/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:plante/outside/backend/backend_products_at_shop.dart';
import 'package:plante/outside/backend/backend_response.dart';
import 'package:plante/outside/backend/backend_shop.dart';
import 'package:plante/outside/backend/mobile_app_config.dart';
import 'package:plante/outside/backend/news/news_data_response.dart';
import 'package:plante/outside/backend/product_at_shop_source.dart';
import 'package:plante/outside/backend/product_presence_vote_result.dart';
import 'package:plante/outside/backend/requested_products_result.dart';
Expand Down Expand Up @@ -366,6 +367,29 @@ class Backend {
..productsCount = 0));
}

Future<Result<NewsDataResponse, BackendError>> requestNews(
CoordsBounds bounds,
{required int page}) async {
final jsonRes = await _backendGetJson('/news_data/', {
'north': '${bounds.north}',
'south': '${bounds.south}',
'west': '${bounds.west}',
'east': '${bounds.east}',
'page': '$page'
});
if (jsonRes.isErr) {
return Err(jsonRes.unwrapErr());
}
final json = jsonRes.unwrap();

try {
return Ok(NewsDataResponse.fromJson(json)!);
} catch (e) {
Log.w('Invalid news_data response: $json', ex: e);
return Err(BackendError.invalidDecodedJson(json));
}
}

Result<None, BackendError> _noneOrErrorFrom(BackendResponse response) {
if (response.isError) {
return Err(_errFromResp(response));
Expand Down
26 changes: 26 additions & 0 deletions lib/outside/backend/news/news_data_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:plante/base/build_value_helper.dart';
import 'package:plante/outside/backend/news/news_piece.dart';

part 'news_data_response.g.dart';

abstract class NewsDataResponse
implements Built<NewsDataResponse, NewsDataResponseBuilder> {
@BuiltValueField(wireName: 'last_page')
bool get lastPage;
@BuiltValueField(wireName: 'results')
BuiltList<NewsPiece> get results;

static NewsDataResponse? fromJson(Map<String, dynamic> json) {
return BuildValueHelper.jsonSerializers
.deserializeWith(NewsDataResponse.serializer, json);
}

factory NewsDataResponse([void Function(NewsDataResponseBuilder) updates]) =
_$NewsDataResponse;
NewsDataResponse._();
static Serializer<NewsDataResponse> get serializer =>
_$newsDataResponseSerializer;
}
173 changes: 173 additions & 0 deletions lib/outside/backend/news/news_data_response.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions lib/outside/backend/news/news_feed_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:plante/base/coord_utils.dart';
import 'package:plante/base/general_error.dart';
import 'package:plante/base/result.dart';
import 'package:plante/logging/log.dart';
import 'package:plante/outside/backend/backend.dart';
import 'package:plante/outside/backend/news/news_piece.dart';
import 'package:plante/ui/map/latest_camera_pos_storage.dart';

class NewsFeedManager {
static const _REQUESTED_AREA_SIZE_KMS = 35.0;
final Backend _backend;
final LatestCameraPosStorage _cameraPosStorage;

NewsFeedManager(this._backend, this._cameraPosStorage);

Future<Result<List<NewsPiece>, GeneralError>> obtainNews(
{required int page}) async {
final pos = await _cameraPosStorage.get();
if (pos == null) {
Log.w('No camera position for some reason');
return Ok(const []);
}
final backendNewsRes = await _backend.requestNews(
pos.makeSquare(kmToGrad(_REQUESTED_AREA_SIZE_KMS)),
page: page);
if (backendNewsRes.isErr) {
return Err(backendNewsRes.unwrapErr().toGeneral());
}
final backendNews = backendNewsRes.unwrap();
return Ok(backendNews.results.toList());
}
}
Loading

0 comments on commit 42ec497

Please sign in to comment.