Skip to content

Commit

Permalink
fix: custom maps dialog confirmation failure ds-33 (#34)
Browse files Browse the repository at this point in the history
* refactor(lib-interfaces): rename route paths constants ds-33

* feat(lib-interfaces): add mixed stories (with & without location fetch combined) ds-33

- Also cache post story picked image state on web reload.

* fix: fix failed custom maps dialog confirmation on post story ds-33
  • Loading branch information
KeidsID authored Feb 7, 2025
1 parent cb85989 commit f057362
Show file tree
Hide file tree
Showing 20 changed files with 707 additions and 575 deletions.
11 changes: 8 additions & 3 deletions lib/domain/entities/story_entity.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import "package:flutter/foundation.dart";
import "package:freezed_annotation/freezed_annotation.dart";
import "package:equatable/equatable.dart";

import "package:dicoding_story_fl/libs/decorators.dart";
import "location_data_entity.dart";

part "story_entity.freezed.dart";
part "story_entity.g.dart";

@Freezed(copyWith: true)
class Story with _$Story {
@Freezed(copyWith: true, equal: false)
class Story with _$Story, EquatableMixin {
const factory Story({
required String id,
@JsonKey(name: "name") required String owner,
Expand All @@ -22,5 +22,10 @@ class Story with _$Story {
@ignoreJsonSerializable LocationData? location,
}) = _Story;

const Story._();

factory Story.fromJson(Map<String, Object?> json) => _$StoryFromJson(json);

@override
List<Object?> get props => [id];
}
8 changes: 4 additions & 4 deletions lib/interfaces/libs/constants.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export "constants/app_route_auth_paths_constant.dart";
export "constants/app_route_paths_constant.dart";
export "constants/app_route_profile_paths_constant.dart";
export "constants/app_route_stories_paths_constant.dart";
export "constants/route_paths/auth_route_paths_constant.dart";
export "constants/route_paths/app_route_paths_constant.dart";
export "constants/route_paths/profile_route_paths_constant.dart";
export "constants/route_paths/stories_route_paths_constant.dart";
export "constants/dark_google_maps_style_constants.dart";
export "constants/date_format_constant.dart";
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// https://mapstyle.withgoogle.com/
const kDarkGoogleMapsStyle = '''
[
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "app_route_paths_constant.dart";

/// Sub paths of [AppRoutePaths.auth].
abstract final class AppRouteAuthPaths {
abstract final class AuthRoutePaths {
static const signIn = "/sign-in";
static const signUp = "/sign-up";
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "app_route_paths_constant.dart";

/// Sub paths of [AppRoutePaths.profile].
abstract final class AppRouteProfilePaths {
abstract final class ProfileRoutePaths {
static const root = "";
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "app_route_paths_constant.dart";

/// Sub paths of [AppRoutePaths.stories].
abstract final class AppRouteStoriesPaths {
abstract final class StoriesRoutePaths {
static const root = "";
static const post = "post";
static const view$storyId = "view/:storyId";
Expand Down
43 changes: 41 additions & 2 deletions lib/interfaces/libs/providers/modules/picked_image_provider.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import "dart:convert";

import "package:camera/camera.dart";
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:image_picker/image_picker.dart";
import "package:shared_preferences/shared_preferences.dart";

import "package:dicoding_story_fl/interfaces/libs/widgets.dart";
import "package:dicoding_story_fl/libs/constants.dart";
import "package:dicoding_story_fl/libs/extensions.dart";
import "package:dicoding_story_fl/service_locator.dart";

import "../libs/types.dart";

Expand All @@ -15,15 +19,42 @@ import "../libs/types.dart";
final class PickedImageProvider extends AsyncValueNotifier<XFile?> {
/// {@macro dicoding_story_fl.interfaces.ux.providers.PickedImageProvider}
PickedImageProvider() : super(null) {
cacheService = ServiceLocator.find<SharedPreferences>();

final cachedImageBytes = cacheService.getString(cacheKey);

if (cachedImageBytes != null) {
final imageBytes = jsonDecode(cachedImageBytes) as List;

value = XFile.fromData(
Uint8List.fromList(
imageBytes.map((e) => e is int ? e : int.parse(e)).toList(),
),
);
}

if (defaultTargetPlatform == TargetPlatform.android) {
Future.microtask(() => _retrieveLostData()).then((_) => null);
}
}

@override
void dispose() {
cacheService.remove(cacheKey);

super.dispose();
}

late final SharedPreferences cacheService;
final cacheKey = "providers.picked_image_provider";

/// Reset [value] to `null`.
///
/// Incase you need it.
void resetValue() => value = null;
void resetValue() {
cacheService.remove(cacheKey);
value = null;
}

/// Pick image from gallery or camera.
///
Expand All @@ -47,6 +78,10 @@ final class PickedImageProvider extends AsyncValueNotifier<XFile?> {

if (dialogResult == null) return null;

cacheService.setString(
cacheKey,
jsonEncode((await dialogResult.readAsBytes()).toList()),
);
value = dialogResult;

return dialogResult;
Expand All @@ -60,6 +95,10 @@ final class PickedImageProvider extends AsyncValueNotifier<XFile?> {

if (image == null) return null;

cacheService.setString(
cacheKey,
jsonEncode((await image.readAsBytes()).toList()),
);
value = image;

return image;
Expand All @@ -84,7 +123,7 @@ final class PickedImageProvider extends AsyncValueNotifier<XFile?> {
}
}

/// `Android` only.
/// `Android` data recovery.
Future<void> _retrieveLostData() async {
isLoading = true;

Expand Down
26 changes: 18 additions & 8 deletions lib/interfaces/libs/providers/modules/stories_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,24 @@ final class StoriesProvider extends AsyncValueNotifier<List<Story>> {
isLoading = true;

try {
final stories = await ServiceLocator.find<GetStoriesUseCase>()
.execute(GetStoriesRequestDto(
page: page,
size: storiesCount,
hasCoordinates: true,
));

if (stories.length < storiesCount) {
final getStoriesUseCase = ServiceLocator.find<GetStoriesUseCase>();

final halfStoriesCount = storiesCount ~/ 2;

final List<Story> stories = {
...(await getStoriesUseCase.execute(GetStoriesRequestDto(
page: page,
size: halfStoriesCount,
hasCoordinates: true,
))),
...(await getStoriesUseCase.execute(GetStoriesRequestDto(
page: page,
size: halfStoriesCount,
))),
}.toList()
..sort((a, b) => b.createdAt.compareTo(a.createdAt));

if (stories.length < halfStoriesCount) {
_isLatestPage = true;
} else {
_page++;
Expand Down
2 changes: 1 addition & 1 deletion lib/interfaces/libs/widgets.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export "widgets/list_tile/app_about_list_tile.dart";
export "widgets/list_tile/locale_list_tile.dart";
export "widgets/list_tile/theme_list_tile.dart";
export "widgets/maps/custom_maps_dialog.dart";
export "widgets/maps/custom_maps_view.dart";
export "widgets/maps/get_location_dialog.dart";
export "widgets/media/common_network_image.dart";
export "widgets/media/custom_camera.dart";
Expand Down
Loading

0 comments on commit f057362

Please sign in to comment.