|
|
@ -132,23 +132,8 @@ class _NewsArticlesViewState extends State<NewsArticlesView> { |
|
|
|
final NewsArticlesBloc bloc, |
|
|
|
final NewsArticlesBloc bloc, |
|
|
|
final NewsArticle article, |
|
|
|
final NewsArticle article, |
|
|
|
final NewsFeed feed, |
|
|
|
final NewsFeed feed, |
|
|
|
) { |
|
|
|
) => |
|
|
|
final clientID = RxBlocProvider.of<AccountsBloc>(context).activeAccount.value!.client.id; |
|
|
|
ListTile( |
|
|
|
|
|
|
|
|
|
|
|
return ResultStreamBuilder<String>( |
|
|
|
|
|
|
|
stream: Provider.of<RequestManager>(context).wrapString( |
|
|
|
|
|
|
|
clientID, |
|
|
|
|
|
|
|
'news-articles-body-${article.id}', |
|
|
|
|
|
|
|
() async => _fixArticleBody(article.body!), |
|
|
|
|
|
|
|
preferCache: true, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
builder: ( |
|
|
|
|
|
|
|
final context, |
|
|
|
|
|
|
|
final bodyData, |
|
|
|
|
|
|
|
final bodyError, |
|
|
|
|
|
|
|
final bodyLoading, |
|
|
|
|
|
|
|
) => |
|
|
|
|
|
|
|
ListTile( |
|
|
|
|
|
|
|
title: Row( |
|
|
|
title: Row( |
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
|
children: [ |
|
|
|
children: [ |
|
|
@ -225,56 +210,53 @@ class _NewsArticlesViewState extends State<NewsArticlesView> { |
|
|
|
bloc.markArticleAsUnread(article); |
|
|
|
bloc.markArticleAsUnread(article); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
onTap: bodyData != null |
|
|
|
onTap: () async { |
|
|
|
? () async { |
|
|
|
final viewType = bloc.newsBloc.options.articleViewTypeOption.value; |
|
|
|
final viewType = bloc.newsBloc.options.articleViewTypeOption.value; |
|
|
|
String? bodyData; |
|
|
|
if (viewType == ArticleViewType.direct) { |
|
|
|
try { |
|
|
|
await Navigator.of(context).push( |
|
|
|
bodyData = _fixArticleBody(article.body!); |
|
|
|
MaterialPageRoute( |
|
|
|
} catch (e, s) { |
|
|
|
builder: (final context) => NewsArticlePage( |
|
|
|
debugPrint(e.toString()); |
|
|
|
bloc: bloc, |
|
|
|
debugPrint(s.toString()); |
|
|
|
article: article, |
|
|
|
} |
|
|
|
useWebView: false, |
|
|
|
|
|
|
|
bodyData: bodyData, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} else if (Provider.of<NeonPlatform>(context, listen: false).canUseWebView && |
|
|
|
|
|
|
|
viewType == ArticleViewType.internalBrowser) { |
|
|
|
|
|
|
|
await Navigator.of(context).push( |
|
|
|
|
|
|
|
MaterialPageRoute( |
|
|
|
|
|
|
|
builder: (final context) => NewsArticlePage( |
|
|
|
|
|
|
|
bloc: bloc, |
|
|
|
|
|
|
|
article: article, |
|
|
|
|
|
|
|
useWebView: true, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (article.unread!) { |
|
|
|
|
|
|
|
bloc.markArticleAsRead(article); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
await launchUrlString( |
|
|
|
|
|
|
|
article.url!, |
|
|
|
|
|
|
|
mode: LaunchMode.externalApplication, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
: null, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String _fixArticleBody(final String b) => _fixTree(html_parser.parse(b).documentElement!).outerHtml; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
html_dom.Element _fixTree(final html_dom.Element element) { |
|
|
|
if (viewType == ArticleViewType.direct && bodyData != null) { |
|
|
|
_fixElement(element); |
|
|
|
await Navigator.of(context).push( |
|
|
|
element.children.forEach(_fixTree); |
|
|
|
MaterialPageRoute( |
|
|
|
|
|
|
|
builder: (final context) => NewsArticlePage( |
|
|
|
|
|
|
|
bloc: bloc, |
|
|
|
|
|
|
|
article: article, |
|
|
|
|
|
|
|
useWebView: false, |
|
|
|
|
|
|
|
bodyData: bodyData, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} else if (Provider.of<NeonPlatform>(context, listen: false).canUseWebView && |
|
|
|
|
|
|
|
viewType == ArticleViewType.internalBrowser) { |
|
|
|
|
|
|
|
await Navigator.of(context).push( |
|
|
|
|
|
|
|
MaterialPageRoute( |
|
|
|
|
|
|
|
builder: (final context) => NewsArticlePage( |
|
|
|
|
|
|
|
bloc: bloc, |
|
|
|
|
|
|
|
article: article, |
|
|
|
|
|
|
|
useWebView: true, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (article.unread!) { |
|
|
|
|
|
|
|
bloc.markArticleAsRead(article); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
await launchUrlString( |
|
|
|
|
|
|
|
article.url!, |
|
|
|
|
|
|
|
mode: LaunchMode.externalApplication, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return element; |
|
|
|
String _fixArticleBody(final String b) => _fixArticleBodyElement(html_parser.parse(b).documentElement!).outerHtml; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
html_dom.Element _fixElement(final html_dom.Element element) { |
|
|
|
html_dom.Element _fixArticleBodyElement(final html_dom.Element element) { |
|
|
|
for (final attributeName in ['src', 'href']) { |
|
|
|
for (final attributeName in ['src', 'href']) { |
|
|
|
final attributeValue = element.attributes[attributeName]; |
|
|
|
final attributeValue = element.attributes[attributeName]; |
|
|
|
if (attributeValue != null && attributeValue.startsWith('//')) { |
|
|
|
if (attributeValue != null && attributeValue.startsWith('//')) { |
|
|
@ -282,6 +264,8 @@ class _NewsArticlesViewState extends State<NewsArticlesView> { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
element.children.forEach(_fixArticleBodyElement); |
|
|
|
|
|
|
|
|
|
|
|
return element; |
|
|
|
return element; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|