Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/core/router/bindings/community_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import 'package:ondo/domain/usecases/post/liked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/load_recommend_post_list_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_like_local_use_case.dart';
import 'package:ondo/domain/usecases/post/unlike_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/unbookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmarked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_bookmark_local_use_case.dart';
import 'package:ondo/presentation/community/controllers/community_controller.dart';
import 'package:ondo/presentation/search/states/search_page_state.dart';

Expand All @@ -20,6 +24,10 @@ class CommunityBinding extends Bindings {
getRecommendPostsUseCase: Get.find<LoadRecommendPostListUseCase>(),
savePostLikeLocalUseCase: Get.find<SavePostLikeLocalUseCase>(),
likedPostUseCase: Get.find<LikedPostUseCase>(),
bookmarkUseCase: Get.find<BookmarkPostUseCase>(),
unbookmarkUseCase: Get.find<UnbookmarkPostUseCase>(),
savePostBookmarkLocalUseCase: Get.find<SavePostBookmarkLocalUseCase>(),
bookmarkedPostUseCase: Get.find<BookmarkedPostUseCase>(),
),
);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/core/router/bindings/home_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import 'package:ondo/domain/usecases/post/liked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/post_search_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_like_local_use_case.dart';
import 'package:ondo/domain/usecases/post/unlike_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/unbookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmarked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_bookmark_local_use_case.dart';
import 'package:ondo/domain/usecases/user/user_search_use_case.dart';
import 'package:ondo/presentation/home/controllers/home_controller.dart';
import 'package:ondo/presentation/search/states/search_page_state.dart';
Expand All @@ -29,6 +33,10 @@ class HomeBinding extends Bindings {
unlikePostUseCase: Get.find<UnlikePostUseCase>(),
savePostLikeLocalUseCase: Get.find<SavePostLikeLocalUseCase>(),
likedPostUseCase: Get.find<LikedPostUseCase>(),
bookmarkPostUseCase: Get.find<BookmarkPostUseCase>(),
unbookmarkPostUseCase: Get.find<UnbookmarkPostUseCase>(),
savePostBookmarkLocalUseCase: Get.find<SavePostBookmarkLocalUseCase>(),
bookmarkedPostUseCase: Get.find<BookmarkedPostUseCase>(),
),
);
}
Expand Down
10 changes: 10 additions & 0 deletions lib/core/router/bindings/post_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import 'package:ondo/data/datasource/post/post_remote_datasource.dart';
import 'package:ondo/data/network/clients/auth_client.dart';
import 'package:ondo/data/repositories/post/post_repository_impl.dart';
import 'package:ondo/domain/usecases/post/bookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmarked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/like_post_usecase.dart';
import 'package:ondo/domain/usecases/post/liked_post_use_case.dart'; // ← 추가
import 'package:ondo/domain/usecases/post/load_recent_popular_post_list_use_case.dart';
import 'package:ondo/domain/usecases/post/load_recommend_post_list_use_case.dart';
import 'package:ondo/domain/usecases/post/post_search_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_bookmark_local_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_like_local_use_case.dart';
import 'package:ondo/domain/usecases/post/unbookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/unlike_post_usecase.dart';
Expand Down Expand Up @@ -52,6 +54,14 @@ class PostBinding extends Bindings {
() => UnbookmarkPostUseCase(Get.find<PostRepositoryImpl>()),
);

Get.lazyPut<BookmarkedPostUseCase>( // ← 로컬 캐시 확인(북마크)
() => BookmarkedPostUseCase(Get.find<PostRepositoryImpl>()),
);

Get.lazyPut<SavePostBookmarkLocalUseCase>(
() => SavePostBookmarkLocalUseCase(Get.find<PostRepositoryImpl>()),
);

Get.lazyPut<PostSearchUseCase>(
() => PostSearchUseCase(Get.find<PostRepositoryImpl>()),
);
Expand Down
8 changes: 8 additions & 0 deletions lib/core/router/bindings/post_view_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import 'package:get/get.dart';
import 'package:ondo/domain/usecases/comment/create_comment_usecase.dart';
import 'package:ondo/domain/usecases/comment/delete_comment_usecase.dart';
import 'package:ondo/domain/usecases/comment/get_comments_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmarked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/liked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_bookmark_local_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_like_local_use_case.dart';

import '../../../data/datasource/comment/comment_remote_datasource.dart';
Expand Down Expand Up @@ -49,6 +51,10 @@ class PostViewBinding extends Bindings {
() => SavePostLikeLocalUseCase(Get.find<PostRepositoryImpl>()),
);

Get.lazyPut<SavePostBookmarkLocalUseCase>(
() => SavePostBookmarkLocalUseCase(Get.find<PostRepositoryImpl>()),
);

// Comment DataSource
Get.lazyPut<CommentRemoteDataSource>(
() => CommentRemoteDataSourceImpl(Get.find<AuthClient>()),
Expand Down Expand Up @@ -90,6 +96,8 @@ class PostViewBinding extends Bindings {
deleteCommentUseCase: Get.find<DeleteCommentUseCase>(),
likedPostUseCase: Get.find<LikedPostUseCase>(),
savePostLikeLocalUseCase: Get.find<SavePostLikeLocalUseCase>(),
bookmarkedPostUseCase: Get.find<BookmarkedPostUseCase>(),
savePostBookmarkLocalUseCase: Get.find<SavePostBookmarkLocalUseCase>(),
),
);
}
Expand Down
35 changes: 35 additions & 0 deletions lib/data/datasource/post/post_local_datasource.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import 'package:shared_preferences/shared_preferences.dart';

class PostLocalDatasource {
static const String _likedPostsKey = 'liked_post_ids';
static const String _bookmarkedPostsKey = 'bookmarked_post_ids';

SharedPreferences? _prefs;
Set<int>? _cachedLikedIds;
Set<int>? _cachedBookmarkedIds;

Future<SharedPreferences> _getPrefs() async {
return _prefs ??= await SharedPreferences.getInstance();
Expand Down Expand Up @@ -42,4 +44,37 @@ class PostLocalDatasource {
final ids = await getLikedPostIds();
return ids.contains(postId);
}

Future<void> saveBookmarkState(int postId, bool isBookmarked) async {
final prefs = await _getPrefs();
final bookmarkedIds = await getBookmarkedPostIds();

if (isBookmarked) {
bookmarkedIds.add(postId);
} else {
bookmarkedIds.remove(postId);
}

_cachedBookmarkedIds = bookmarkedIds;

await prefs.setStringList(
_bookmarkedPostsKey,
bookmarkedIds.map((id) => id.toString()).toList(),
);
}

Future<Set<int>> getBookmarkedPostIds() async {
if (_cachedBookmarkedIds != null) return _cachedBookmarkedIds!;

final prefs = await _getPrefs();
final ids = prefs.getStringList(_bookmarkedPostsKey);
_cachedBookmarkedIds =
(ids ?? []).map((id) => int.tryParse(id)).whereType<int>().toSet();
return _cachedBookmarkedIds!;
}

Future<bool> bookmarkedPost(int postId) async {
final ids = await getBookmarkedPostIds();
return ids.contains(postId);
}
}
10 changes: 10 additions & 0 deletions lib/data/repositories/post/post_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ class PostRepositoryImpl implements PostRepository {
return _localDatasource.likedPost(postId);
}

@override
Future<void> saveBookmarkState(int postId, bool isBookmarked) {
return _localDatasource.saveBookmarkState(postId, isBookmarked);
}

@override
Future<bool> bookmarkedPost(int postId) {
return _localDatasource.bookmarkedPost(postId);
}

@override
Future<ListableWrapper<PostEntity>> search(
String keyword,
Expand Down
11 changes: 11 additions & 0 deletions lib/domain/entities/post/bookmark_changed_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class BookmarkChangedEvent {
final int postId;
final bool isBookmarked;
final int bookmarkCount;

BookmarkChangedEvent({
required this.postId,
required this.isBookmarked,
required this.bookmarkCount,
});
}
31 changes: 19 additions & 12 deletions lib/domain/entities/post/post_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@ class PostEntity {
this.isBookmark = false,
});

PostEntity copyWith({int? likeCount, bool? isFavorite}) => PostEntity(
postId: postId,
title: title,
authorName: authorName,
tags: tags,
viewCount: viewCount,
likeCount: likeCount ?? this.likeCount,
commentCount: commentCount,
bookmarkCount: bookmarkCount,
createAt: createAt,
isFavorite: isFavorite ?? this.isFavorite,
);
PostEntity copyWith({
int? likeCount,
bool? isFavorite,
int? bookmarkCount,
bool? isBookmark,
}) =>
PostEntity(
postId: postId,
title: title,
authorName: authorName,
tags: tags,
viewCount: viewCount,
likeCount: likeCount ?? this.likeCount,
commentCount: commentCount,
bookmarkCount: bookmarkCount ?? this.bookmarkCount,
createAt: createAt,
isFavorite: isFavorite ?? this.isFavorite,
isBookmark: isBookmark ?? this.isBookmark,
);

PostEntity.fromPostModel(PostModel model)
: postId = model.postId,
Expand Down
4 changes: 4 additions & 0 deletions lib/domain/repositories/post/post_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ abstract class PostRepository {

Future<bool> likedPost(int postId);

Future<void> saveBookmarkState(int postId, bool isBookmarked);

Future<bool> bookmarkedPost(int postId);

Future<ListableWrapper<PostEntity>> search(
String keyword,
List<String>? tags,
Expand Down
11 changes: 11 additions & 0 deletions lib/domain/usecases/post/bookmarked_post_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:ondo/domain/repositories/post/post_repository.dart';

class BookmarkedPostUseCase {
final PostRepository _repository;

BookmarkedPostUseCase(this._repository);

Future<bool> call(int postId) {
return _repository.bookmarkedPost(postId);
}
}
11 changes: 11 additions & 0 deletions lib/domain/usecases/post/save_post_bookmark_local_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:ondo/domain/repositories/post/post_repository.dart';

class SavePostBookmarkLocalUseCase {
final PostRepository _repository;

SavePostBookmarkLocalUseCase(this._repository);

Future<void> call(int postId, bool isBookmarked) {
return _repository.saveBookmarkState(postId, isBookmarked);
}
}
73 changes: 72 additions & 1 deletion lib/presentation/community/controllers/community_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import 'package:ondo/domain/usecases/post/liked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_like_local_use_case.dart';
import 'package:ondo/domain/usecases/post/unlike_post_usecase.dart';
import 'package:ondo/domain/usecases/post/update_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/unbookmark_post_usecase.dart';
import 'package:ondo/domain/usecases/post/bookmarked_post_use_case.dart';
import 'package:ondo/domain/usecases/post/save_post_bookmark_local_use_case.dart';
import 'package:ondo/presentation/community/controllers/community_post_create_screen_controller.dart';
import 'package:ondo/presentation/community/screens/community_post_create_screen.dart';
import 'package:ondo/presentation/post/controllers/post_controller.dart';
Expand All @@ -18,18 +22,30 @@ class CommunityController extends GetxController {
final LoadRecommendPostListUseCase _getRecommendPostsUseCase;
final SavePostLikeLocalUseCase _savePostLikeLocalUseCase;
final LikedPostUseCase _likedPostUseCase;
final BookmarkPostUseCase _bookmarkUseCase;
final UnbookmarkPostUseCase _unbookmarkUseCase;
final SavePostBookmarkLocalUseCase _savePostBookmarkLocalUseCase;
final BookmarkedPostUseCase _bookmarkedPostUseCase;

CommunityController({
required LikePostUseCase likeUseCase,
required UnlikePostUseCase unlikeUseCase,
required LoadRecommendPostListUseCase getRecommendPostsUseCase,
required SavePostLikeLocalUseCase savePostLikeLocalUseCase,
required LikedPostUseCase likedPostUseCase,
required BookmarkPostUseCase bookmarkUseCase,
required UnbookmarkPostUseCase unbookmarkUseCase,
required SavePostBookmarkLocalUseCase savePostBookmarkLocalUseCase,
required BookmarkedPostUseCase bookmarkedPostUseCase,
}) : _likeUseCase = likeUseCase,
_unlikeUseCase = unlikeUseCase,
_getRecommendPostsUseCase = getRecommendPostsUseCase,
_savePostLikeLocalUseCase = savePostLikeLocalUseCase,
_likedPostUseCase = likedPostUseCase;
_likedPostUseCase = likedPostUseCase,
_bookmarkUseCase = bookmarkUseCase,
_unbookmarkUseCase = unbookmarkUseCase,
_savePostBookmarkLocalUseCase = savePostBookmarkLocalUseCase,
_bookmarkedPostUseCase = bookmarkedPostUseCase;

final RxSet<String> viewTagList = <String>{}.obs;
final RxSet<String> selectTagList = <String>{}.obs;
Expand All @@ -55,6 +71,14 @@ class CommunityController extends GetxController {
_syncLike(event.postId, event.isLiked, event.likeCount);
},
);

ever(
Get.find<PostController>().lastBookmarkEvent,
(event) {
if (event == null) return;
_syncBookmark(event.postId, event.isBookmarked, event.bookmarkCount);
},
);
}

void _syncLike(int postId, bool isLiked, int likeCount) {
Expand All @@ -68,6 +92,17 @@ class CommunityController extends GetxController {
}
}

void _syncBookmark(int postId, bool isBookmarked, int bookmarkCount) {
final cacheIndex = _cachePostList.indexWhere((p) => p.postId == postId);
if (cacheIndex != -1) {
_cachePostList[cacheIndex] = _cachePostList[cacheIndex].copyWith(
bookmarkCount: bookmarkCount,
isBookmark: isBookmarked,
);
viewPostList.assignAll(_cachePostList);
}
}
Comment thread
ryusuye0n marked this conversation as resolved.

@override
void onReady() {
Get.put(CommunityResultController());
Expand Down Expand Up @@ -96,6 +131,7 @@ class CommunityController extends GetxController {
result.content.map((post) async {
return post.copyWith(
isFavorite: await _likedPostUseCase(post.postId),
isBookmark: await _bookmarkedPostUseCase(post.postId),
);
}),
);
Expand Down Expand Up @@ -165,6 +201,41 @@ class CommunityController extends GetxController {
}
}

Future<void> toggleBookmark(int postId, bool isBookmarked) async {
_updatePostBookmarkInList(postId, isBookmarked ? 1 : -1, isBookmarked);

try {
if (isBookmarked) {
await _bookmarkUseCase(postId);
} else {
await _unbookmarkUseCase(postId);
}
await _savePostBookmarkLocalUseCase(postId, isBookmarked);
} catch (e) {
debugPrint('[CommunityController] 북마크 토글 실패 - error: $e');
_updatePostBookmarkInList(postId, isBookmarked ? -1 : 1, !isBookmarked);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳이 빼는 값을 함수의 인자로 넘기는 것 보다는,
해당 로직을 함수 내에 정의하는 구조가 더 나을 듯 합니다.

}
}

void _updatePostBookmarkInList(int postId, int delta, bool isBookmark) {
final index = viewPostList.indexWhere((p) => p.postId == postId);
if (index != -1) {
viewPostList[index] = viewPostList[index].copyWith(
bookmarkCount: viewPostList[index].bookmarkCount + delta,
isBookmark: isBookmark,
);
viewPostList.refresh();
}

final cacheIndex = _cachePostList.indexWhere((p) => p.postId == postId);
if (cacheIndex != -1) {
_cachePostList[cacheIndex] = _cachePostList[cacheIndex].copyWith(
bookmarkCount: _cachePostList[cacheIndex].bookmarkCount + delta,
isBookmark: isBookmark,
);
}
}

void removePost(int postId) {
viewPostList.removeWhere((p) => p.postId == postId);
_cachePostList.removeWhere((p) => p.postId == postId);
Expand Down
3 changes: 3 additions & 0 deletions lib/presentation/community/widgets/community_post_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class CommunityPostList extends GetView<CommunityController> {
heartAction: (isLiked, total) {
controller.toggleLike(post.postId, isLiked);
},
bookmarkAction: (isBookmark, total) {
controller.toggleBookmark(post.postId, isBookmark);
},
);
},
),
Expand Down
Loading
Loading