// ๐Ÿ—ฃ๏ธ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ - ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํ™”๋ฉด์˜ ๊ธฐ๋Šฅ(์„œ๋ฒ„ ํ†ต์‹ /์ƒํƒœ) ๋‹ด๋‹น ์ปจํŠธ๋กค๋Ÿฌ. import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import '../config.dart'; class BoardListController extends ChangeNotifier { final String category; final String studentId; BoardListController({required this.category, required this.studentId}); bool _isLoading = true; bool _isLoadingMore = false; bool _hasMore = true; int _page = 1; List _posts = []; bool _disposed = false; bool get isLoading => _isLoading; bool get isLoadingMore => _isLoadingMore; bool get hasMore => _hasMore; List get posts => _posts; static const int _pageSize = 20; void _safeNotify() { if (!_disposed) notifyListeners(); } @override void dispose() { _disposed = true; super.dispose(); } Future init() => refresh(); Future refresh() async { _isLoading = true; _page = 1; _hasMore = true; _safeNotify(); await _fetchPage(replace: true); _isLoading = false; _safeNotify(); } Future loadMore() async { if (_isLoadingMore || !_hasMore || _isLoading) return; _isLoadingMore = true; _safeNotify(); _page += 1; await _fetchPage(replace: false); _isLoadingMore = false; _safeNotify(); } Future _fetchPage({required bool replace}) async { try { final response = await http.get( Uri.parse( '$baseUrl/api/board/posts?category=$category&studentId=$studentId&page=$_page', ), ); if (response.statusCode == 200) { final data = jsonDecode(utf8.decode(response.bodyBytes)); final fetched = (data['posts'] as List?) ?? []; _posts = replace ? fetched : [..._posts, ...fetched]; _hasMore = fetched.length >= _pageSize; } } catch (_) { // ์กฐ์šฉํžˆ ๋ฌด์‹œ - ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐ›์•„์˜จ ๋ชฉ๋ก์„ ์œ ์ง€ํ•œ๋‹ค. } } }