mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
d1c8eed3de |
@ -6,6 +6,8 @@ import 'package:hacki/config/constants.dart';
|
||||
import 'package:hacki/styles/styles.dart';
|
||||
|
||||
extension ContextExtension on BuildContext {
|
||||
bool get isScreenReaderEnabled => MediaQuery.of(this).accessibleNavigation;
|
||||
|
||||
T? tryRead<T>() {
|
||||
try {
|
||||
return read<T>();
|
||||
|
@ -1,5 +1,5 @@
|
||||
extension DateTimeExtension on DateTime {
|
||||
String toReadableString() {
|
||||
String toTimeAgoString() {
|
||||
final DateTime now = DateTime.now();
|
||||
final Duration diff = now.difference(this);
|
||||
if (diff.inDays > 365) {
|
||||
|
@ -24,7 +24,7 @@ class Comment extends Item {
|
||||
|
||||
final int level;
|
||||
|
||||
String get metadata => '''by $by $postedDate''';
|
||||
String get metadata => '''by $by $timeAgo''';
|
||||
|
||||
Comment copyWith({int? level}) {
|
||||
return Comment(
|
||||
|
@ -82,8 +82,8 @@ class Item extends Equatable {
|
||||
final List<int> kids;
|
||||
final List<int> parts;
|
||||
|
||||
String get postedDate =>
|
||||
DateTime.fromMillisecondsSinceEpoch(time * 1000).toReadableString();
|
||||
String get timeAgo =>
|
||||
DateTime.fromMillisecondsSinceEpoch(time * 1000).toTimeAgoString();
|
||||
|
||||
bool get isPoll => type == 'poll';
|
||||
|
||||
|
@ -43,10 +43,13 @@ class Story extends Item {
|
||||
Story.fromJson(super.json) : super.fromJson();
|
||||
|
||||
String get metadata =>
|
||||
'''$score point${score > 1 ? 's' : ''} by $by $postedDate | $descendants comment${descendants > 1 ? 's' : ''}''';
|
||||
'''$score point${score > 1 ? 's' : ''} by $by $timeAgo | $descendants comment${descendants > 1 ? 's' : ''}''';
|
||||
|
||||
String get screenReaderLabel =>
|
||||
'''$title at $readableUrl by $by $timeAgo. This story has $score point${score > 1 ? 's' : ''} and $descendants comment${descendants > 1 ? 's' : ''}''';
|
||||
|
||||
String get simpleMetadata =>
|
||||
'''$score point${score > 1 ? 's' : ''} $descendants comment${descendants > 1 ? 's' : ''} $postedDate''';
|
||||
'''$score point${score > 1 ? 's' : ''} $descendants comment${descendants > 1 ? 's' : ''} $timeAgo''';
|
||||
|
||||
String get readableUrl {
|
||||
final Uri url = Uri.parse(this.url);
|
||||
@ -55,10 +58,5 @@ class Story extends Item {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
// final String prettyString =
|
||||
// const JsonEncoder.withIndent(' ').convert(this);
|
||||
// return 'Story $prettyString';
|
||||
return 'Story $id';
|
||||
}
|
||||
String toString() => 'Story $id';
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ class LinkIconButton extends StatelessWidget {
|
||||
featureId: Constants.featureOpenStoryInWebView,
|
||||
title: Text('Open in Browser'),
|
||||
description: Text(
|
||||
'Want more than just reading and replying? '
|
||||
'You can tap here to open this story in a '
|
||||
'browser.',
|
||||
'''You can tap here to open this story in browser.''',
|
||||
style: TextStyle(fontSize: TextDimens.pt16),
|
||||
),
|
||||
child: Icon(
|
||||
|
@ -286,7 +286,7 @@ class _ParentItemSection extends StatelessWidget {
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
state.item.postedDate,
|
||||
state.item.timeAgo,
|
||||
style: const TextStyle(
|
||||
color: Palette.grey,
|
||||
),
|
||||
|
@ -118,7 +118,7 @@ class InboxView extends StatelessWidget {
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
e.postedDate,
|
||||
e.timeAgo,
|
||||
style: const TextStyle(
|
||||
color: Palette.grey,
|
||||
),
|
||||
|
@ -152,7 +152,7 @@ class CommentTile extends StatelessWidget {
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
comment.postedDate,
|
||||
comment.timeAgo,
|
||||
style: const TextStyle(
|
||||
color: Palette.grey,
|
||||
),
|
||||
|
@ -317,6 +317,7 @@ class SelectableLinkify extends StatelessWidget {
|
||||
selectionControls: selectionControls,
|
||||
onSelectionChanged: onSelectionChanged,
|
||||
contextMenuBuilder: contextMenuBuilder,
|
||||
semanticsLabel: text,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ class ItemText extends StatelessWidget {
|
||||
editableTextState,
|
||||
item: item,
|
||||
),
|
||||
semanticsLabel: item.text,
|
||||
);
|
||||
} else {
|
||||
return SelectableLinkify(
|
||||
|
@ -200,7 +200,7 @@ class ItemsListView<T extends Item> extends StatelessWidget {
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
e.postedDate,
|
||||
e.timeAgo,
|
||||
style: const TextStyle(
|
||||
color: Palette.grey,
|
||||
),
|
||||
|
@ -52,15 +52,18 @@ class _OnboardingViewState extends State<OnboardingView> {
|
||||
children: const <Widget>[
|
||||
_PageViewChild(
|
||||
path: Constants.commentTileRightSlidePath,
|
||||
description: 'Swipe right to leave a comment or vote.',
|
||||
description:
|
||||
'''Swipe right to leave a comment, vote, and more.''',
|
||||
),
|
||||
_PageViewChild(
|
||||
path: Constants.commentTileLeftSlidePath,
|
||||
description: 'Swipe left to view all the parent comments.',
|
||||
description:
|
||||
'''Swipe left to view all the ancestor comments.''',
|
||||
),
|
||||
_PageViewChild(
|
||||
path: Constants.commentTileTopTapPath,
|
||||
description: 'Tap on the top of comment tile to collapse.',
|
||||
description:
|
||||
'''Tap on anywhere inside a comment tile to collapse.''',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -33,7 +33,9 @@ class StoryTile extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
if (showWebPreview) {
|
||||
final double height = context.storyTileHeight;
|
||||
return TapDownWrapper(
|
||||
return Semantics(
|
||||
label: story.screenReaderLabel,
|
||||
child: TapDownWrapper(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
@ -43,7 +45,8 @@ class StoryTile extends StatelessWidget {
|
||||
child: LinkPreview(
|
||||
story: story,
|
||||
link: story.url,
|
||||
offlineReading: context.read<StoriesBloc>().state.offlineReading,
|
||||
offlineReading:
|
||||
context.read<StoriesBloc>().state.offlineReading,
|
||||
placeholderWidget: _LinkPreviewPlaceholder(
|
||||
height: height,
|
||||
),
|
||||
@ -64,9 +67,12 @@ class StoryTile extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return InkWell(
|
||||
return Semantics(
|
||||
label: story.screenReaderLabel,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: Dimens.pt12),
|
||||
@ -130,6 +136,7 @@ class StoryTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1359,4 +1359,4 @@ packages:
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
flutter: ">=3.7.5"
|
||||
flutter: ">=3.7.6"
|
||||
|
@ -1,11 +1,11 @@
|
||||
name: hacki
|
||||
description: A Hacker News reader.
|
||||
version: 1.3.1+100
|
||||
version: 1.3.2+101
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
flutter: "3.7.5"
|
||||
flutter: "3.7.6"
|
||||
|
||||
dependencies:
|
||||
adaptive_theme: ^3.0.0
|
||||
|
Submodule submodules/flutter updated: c07f788888...12cb4eb7a0
Reference in New Issue
Block a user