Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@
"@database": {},
"databaseSettings": "Database settings",
"@databaseSettings": {},
"scrapeAbstracts": "Scrape missing abstracts",
"@scrapeAbstracts":{},
"cleanupInterval": "Cleanup interval (days)",
"@cleanupInterval": {},
"cleanupIntervalHint": "Enter number of days (1 to 365)",
Expand Down
79 changes: 77 additions & 2 deletions lib/screens/article_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import '../widgets/publication_card.dart';
import './journals_details_screen.dart';
import '../services/zotero_api.dart';
import '../services/string_format_helper.dart';
import '../services/abstract_scraper.dart';
import 'package:share_plus/share_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';

class ArticleScreen extends StatefulWidget {
final String doi;
Expand All @@ -22,6 +24,7 @@ class ArticleScreen extends StatefulWidget {
final String license;
final String licenseName;
final String? publisher;
final VoidCallback? onAbstractChanged;

const ArticleScreen({
Key? key,
Expand All @@ -36,6 +39,7 @@ class ArticleScreen extends StatefulWidget {
required this.license,
required this.licenseName,
this.publisher,
this.onAbstractChanged,
}) : super(key: key);

@override
Expand All @@ -45,12 +49,17 @@ class ArticleScreen extends StatefulWidget {
class _ArticleScreenState extends State<ArticleScreen> {
bool isLiked = false;
late DatabaseHelper databaseHelper;
String? abstract;
bool isLoadingAbstract = false;
bool _scrapeAbstracts = true;

@override
void initState() {
super.initState();
databaseHelper = DatabaseHelper();
_loadScrapingSettings();
checkIfLiked();
abstract = widget.abstract;
}

void _onShare(BuildContext context) async {
Expand All @@ -65,6 +74,58 @@ class _ArticleScreenState extends State<ArticleScreen> {
}
}

Future<void> _loadScrapingSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_scrapeAbstracts = prefs.getBool('scrapeAbstracts') ?? true;
});
if (_scrapeAbstracts) {
final missingAbstractText =
AppLocalizations.of(context)!.abstractunavailable;

if (abstract == null ||
abstract!.isEmpty ||
abstract == missingAbstractText) {
fetchAbstract();
}
}
}

Future<void> fetchAbstract() async {
if (!mounted) return;
setState(() {
isLoadingAbstract = true;
});

//debugPrint("Calling scraper for: ${widget.url}");

AbstractScraper scraper = AbstractScraper();
String? scraped;
try {
scraped = await scraper.scrapeAbstract(widget.url);
} catch (e) {
scraped = '';
}
String finalAbstract = '';
if (scraped != null && scraped.isNotEmpty) {
finalAbstract = scraped;
try {
databaseHelper.updateArticleAbstract(widget.doi, finalAbstract);
widget.onAbstractChanged!();
} catch (e) {
debugPrint("Unable to update the abstract: ${e}");
}
} else {
finalAbstract = AppLocalizations.of(context)!.abstractunavailable;
}
if (!mounted) return;
setState(() {
abstract = finalAbstract;
isLoadingAbstract = false;
});
// debugPrint("Final Abstract: $abstract");
}

@override
Widget build(BuildContext context) {
return Scaffold(
Expand Down Expand Up @@ -106,13 +167,27 @@ class _ArticleScreenState extends State<ArticleScreen> {
SelectableText(getAuthorsNames(widget.authors),
style: TextStyle(color: Colors.grey, fontSize: 15)),
SizedBox(height: 15),
SelectableText(
isLoadingAbstract
? Center(child: CircularProgressIndicator())
: abstract != null && abstract!.isNotEmpty
? SelectableText(
abstract!,
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 16),
)
: Text(
AppLocalizations.of(context)!.abstractunavailable,
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 16),
),

/*SelectableText(
widget.abstract.isNotEmpty
? widget.abstract
: AppLocalizations.of(context)!.abstractunavailable,
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 16),
),
),*/
SizedBox(height: 20),
Row(
children: [
Expand Down
19 changes: 19 additions & 0 deletions lib/screens/database_settings_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class DatabaseSettingsScreen extends StatefulWidget {
class _DatabaseSettingsScreenState extends State<DatabaseSettingsScreen> {
final _formKey = GlobalKey<FormState>();

bool _scrapeAbstracts = true; // Default to scraping missing abstracts
int _cleanupInterval = 7; // Default for cleanup interval
int _fetchInterval = 6; // Default API fetch to 6 hours
TextEditingController _cleanupIntervalController = TextEditingController();
Expand All @@ -35,6 +36,7 @@ class _DatabaseSettingsScreenState extends State<DatabaseSettingsScreen> {
// Load the values from SharedPreferences if available
_cleanupInterval = prefs.getInt('cleanupInterval') ?? 7;
_fetchInterval = prefs.getInt('fetchInterval') ?? 6;
_scrapeAbstracts = prefs.getBool('scrapeAbstracts') ?? true;
});
_cleanupIntervalController.text = _cleanupInterval.toString();
}
Expand All @@ -45,6 +47,7 @@ class _DatabaseSettingsScreenState extends State<DatabaseSettingsScreen> {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('cleanupInterval', _cleanupInterval);
await prefs.setInt('fetchInterval', _fetchInterval);
await prefs.setBool('scrapeAbstracts', _scrapeAbstracts);

ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context)!.settingsSaved)),
Expand Down Expand Up @@ -221,6 +224,22 @@ class _DatabaseSettingsScreenState extends State<DatabaseSettingsScreen> {
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.scrapeAbstracts,
),
Switch(
value: _scrapeAbstracts,
onChanged: (bool value) async {
setState(() {
_scrapeAbstracts = value;
});
},
),
],
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _saveSettings,
Expand Down
4 changes: 2 additions & 2 deletions lib/screens/display_settings_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class DisplaySettingsScreen extends StatefulWidget {
}

class _DisplaySettingsScreenState extends State<DisplaySettingsScreen> {
int _publicationCardOption = 0;
int _publicationCardOption = 1;

@override
void initState() {
Expand All @@ -24,7 +24,7 @@ class _DisplaySettingsScreenState extends State<DisplaySettingsScreen> {
final prefs = await SharedPreferences.getInstance();
setState(() {
_publicationCardOption = prefs.getInt('publicationCardAbstractSetting') ??
0; // Default to "show all abstracts"
1; // Default to "hide missing abstracts"
});
}

Expand Down
25 changes: 25 additions & 0 deletions lib/screens/favorites_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class FavoritesScreen extends StatefulWidget {

class _FavoritesScreenState extends State<FavoritesScreen> {
late Future<List<PublicationCard>> _favoriteArticles;
late ScrollController _scrollController;
int sortBy = 0; // Set the sort by option to Article title by default
int sortOrder = 0; // Set the sort order to Ascending by default
Map<String, String> abstractCache = {}; // Cache for abstracts
Expand All @@ -27,6 +28,7 @@ class _FavoritesScreenState extends State<FavoritesScreen> {
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_favoriteArticles = _loadFavoriteArticles();

_filterController.addListener(() {
Expand All @@ -36,12 +38,20 @@ class _FavoritesScreenState extends State<FavoritesScreen> {

Future<List<PublicationCard>> _loadFavoriteArticles() async {
try {
final double previousOffset = _scrollController.hasClients
? _scrollController.offset
: 0; // Save scroll position
List<PublicationCard> favorites =
await DatabaseHelper().getFavoriteArticles();
setState(() {
_allFavorites = favorites;
_filteredFavorites = _sortFavorites(favorites); // Apply sorting
});
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_scrollController.hasClients) {
_scrollController.jumpTo(previousOffset); // Restore scroll position
}
});
return favorites;
} catch (e) {
throw Exception('Failed to load favorite articles: $e');
Expand Down Expand Up @@ -156,6 +166,7 @@ class _FavoritesScreenState extends State<FavoritesScreen> {
),
)
: ListView.builder(
controller: _scrollController,
itemCount: _filteredFavorites.length,
itemBuilder: (context, index) {
final publicationCard = _filteredFavorites[index];
Expand All @@ -179,6 +190,9 @@ class _FavoritesScreenState extends State<FavoritesScreen> {
onFavoriteChanged: () {
_removeFavorite(context, publicationCard);
},
onAbstractChanged: () {
_updateAbstract();
},
);
} else {
// Use the AbstractHelper to get the formatted abstract
Expand Down Expand Up @@ -218,6 +232,9 @@ class _FavoritesScreenState extends State<FavoritesScreen> {
onFavoriteChanged: () {
_removeFavorite(context, publicationCard);
},
onAbstractChanged: () {
_updateAbstract();
},
);
}
},
Expand Down Expand Up @@ -328,9 +345,17 @@ class _FavoritesScreenState extends State<FavoritesScreen> {
);
}

Future<void> _updateAbstract() async {
setState(() {
abstractCache = {};
_favoriteArticles = _loadFavoriteArticles();
});
}

@override
void dispose() {
_filterController.dispose();
_scrollController.dispose();
super.dispose();
}
}
20 changes: 19 additions & 1 deletion lib/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ class _HomeScreenState extends State<HomeScreen> {
final FeedService _feedService = FeedService();

List<Map<String, dynamic>> savedQueries = [];
bool _feedLoaded = false; // Needed to avoid conflicts wih onAbstractChanged

@override
void initState() {
super.initState();
_loadFetchInterval();
_buildAndStreamFeed();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_feedLoaded) {
_onAbstractChanged();
}
});

_filterController.addListener(() {
_filterFeed(_filterController.text);
Expand Down Expand Up @@ -95,12 +101,13 @@ class _HomeScreenState extends State<HomeScreen> {

if (mounted) {
final List<PublicationCard> cachedFeed =
await _feedService.getCachedFeed(context);
await _feedService.getCachedFeed(context, _onAbstractChanged);

setState(() {
_allFeed = List.from(cachedFeed);
_filteredFeed = List.from(_allFeed);
_sortFeed();
_feedLoaded = true;
});

_feedStreamController.add(_filteredFeed);
Expand Down Expand Up @@ -181,6 +188,17 @@ class _HomeScreenState extends State<HomeScreen> {
});
}

void _onAbstractChanged() async {
final List<PublicationCard> cachedFeed =
await _feedService.getCachedFeed(context, _onAbstractChanged);
setState(() {
_allFeed = List.from(cachedFeed);
_filterFeed(_filterController.text);
_sortFeed();
_feedStreamController.add(_filteredFeed);
});
}

void handleMenuButton(int item) {
switch (item) {
case 0:
Expand Down
2 changes: 1 addition & 1 deletion lib/services/abstract_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ enum AbstractSetting { showAll, hideAll, hideMissing }
class AbstractHelper {
static Future<AbstractSetting> getAbstractSetting() async {
final prefs = await SharedPreferences.getInstance();
final int setting = prefs.getInt('publicationCardAbstractSetting') ?? 0;
final int setting = prefs.getInt('publicationCardAbstractSetting') ?? 1;

switch (setting) {
case 1:
Expand Down
Loading