mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
c7824eaef3 | |||
c2b66d29c3 | |||
e0a53e44b2 | |||
4cf8379db0 | |||
c1c26bf0e0 |
4
.github/workflows/commit_check.yml
vendored
4
.github/workflows/commit_check.yml
vendored
@ -12,12 +12,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.7.0"
|
FLUTTER_VERSION: "3.7.2"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
flutter-version: '3.7.0'
|
flutter-version: '3.7.2'
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
- run: flutter pub get
|
- run: flutter pub get
|
||||||
- run: flutter format --set-exit-if-changed .
|
- run: flutter format --set-exit-if-changed .
|
||||||
|
2
.github/workflows/publish_ios.yml
vendored
2
.github/workflows/publish_ios.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
cache: true
|
cache: true
|
||||||
flutter-version: 3.7.0
|
flutter-version: 3.7.2
|
||||||
- run: flutter pub get
|
- run: flutter pub get
|
||||||
- run: flutter format --set-exit-if-changed .
|
- run: flutter format --set-exit-if-changed .
|
||||||
- run: flutter analyze
|
- run: flutter analyze
|
||||||
|
3
fastlane/metadata/android/en-US/changelogs/84.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/84.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
- Customization of tab bar.
|
||||||
|
- Option to enable swipe gesture for switching between tabs.
|
||||||
|
- Access to action menu from home screen.
|
@ -119,11 +119,45 @@ extension StateExtension on State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onShareTapped(Item item, Rect? rect) {
|
Future<void> onShareTapped(Item item, Rect? rect) async {
|
||||||
Share.share(
|
late final String? linkToShare;
|
||||||
'https://news.ycombinator.com/item?id=${item.id}',
|
if (item.url.isNotEmpty) {
|
||||||
sharePositionOrigin: rect,
|
linkToShare = await showModalBottomSheet<String>(
|
||||||
);
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: 140,
|
||||||
|
color: Theme.of(context).canvasColor,
|
||||||
|
child: Material(
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ListTile(
|
||||||
|
onTap: () => Navigator.pop(context, item.url),
|
||||||
|
title: const Text('Link to article'),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
onTap: () => Navigator.pop(
|
||||||
|
context,
|
||||||
|
'https://news.ycombinator.com/item?id=${item.id}',
|
||||||
|
),
|
||||||
|
title: const Text('Link to HN'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
linkToShare = 'https://news.ycombinator.com/item?id=${item.id}';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkToShare != null) {
|
||||||
|
await Share.share(
|
||||||
|
linkToShare,
|
||||||
|
sharePositionOrigin: rect,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFlagTapped(Item item) {
|
void onFlagTapped(Item item) {
|
||||||
|
@ -9,4 +9,5 @@ export 'post_data.dart';
|
|||||||
export 'preference.dart';
|
export 'preference.dart';
|
||||||
export 'search_params.dart';
|
export 'search_params.dart';
|
||||||
export 'story.dart';
|
export 'story.dart';
|
||||||
|
export 'story_type.dart';
|
||||||
export 'user.dart';
|
export 'user.dart';
|
||||||
|
@ -24,22 +24,7 @@ class PollOption extends Item {
|
|||||||
|
|
||||||
PollOption.empty()
|
PollOption.empty()
|
||||||
: ratio = 0,
|
: ratio = 0,
|
||||||
super(
|
super.empty();
|
||||||
id: 0,
|
|
||||||
score: 0,
|
|
||||||
descendants: 0,
|
|
||||||
time: 0,
|
|
||||||
by: '',
|
|
||||||
title: '',
|
|
||||||
url: '',
|
|
||||||
kids: <int>[],
|
|
||||||
dead: false,
|
|
||||||
parts: <int>[],
|
|
||||||
deleted: false,
|
|
||||||
parent: 0,
|
|
||||||
text: '',
|
|
||||||
type: '',
|
|
||||||
);
|
|
||||||
|
|
||||||
PollOption.fromJson(super.json)
|
PollOption.fromJson(super.json)
|
||||||
: ratio = 0,
|
: ratio = 0,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:collection';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
@ -13,26 +14,29 @@ abstract class Preference<T> extends Equatable with SettingsDisplayable {
|
|||||||
|
|
||||||
Preference<T> copyWith({required T? val});
|
Preference<T> copyWith({required T? val});
|
||||||
|
|
||||||
static List<Preference<dynamic>> allPreferences = <Preference<dynamic>>[
|
static final List<Preference<dynamic>> allPreferences =
|
||||||
// Order of these first three preferences does not matter.
|
UnmodifiableListView<Preference<dynamic>>(
|
||||||
FetchModePreference(),
|
<Preference<dynamic>>[
|
||||||
CommentsOrderPreference(),
|
// Order of these first four preferences does not matter.
|
||||||
FontSizePreference(),
|
FetchModePreference(),
|
||||||
TabOrderPreference(),
|
CommentsOrderPreference(),
|
||||||
// Order of items below matters and
|
FontSizePreference(),
|
||||||
// reflects the order on settings screen.
|
TabOrderPreference(),
|
||||||
const DisplayModePreference(),
|
// Order of items below matters and
|
||||||
const MetadataModePreference(),
|
// reflects the order on settings screen.
|
||||||
const StoryUrlModePreference(),
|
const DisplayModePreference(),
|
||||||
const NotificationModePreference(),
|
const MetadataModePreference(),
|
||||||
const SwipeGesturePreference(),
|
const StoryUrlModePreference(),
|
||||||
const CollapseModePreference(),
|
const NotificationModePreference(),
|
||||||
NavigationModePreference(),
|
const SwipeGesturePreference(),
|
||||||
const ReaderModePreference(),
|
const CollapseModePreference(),
|
||||||
const MarkReadStoriesModePreference(),
|
NavigationModePreference(),
|
||||||
const EyeCandyModePreference(),
|
const ReaderModePreference(),
|
||||||
const TrueDarkModePreference(),
|
const MarkReadStoriesModePreference(),
|
||||||
];
|
const EyeCandyModePreference(),
|
||||||
|
const TrueDarkModePreference(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => <Object?>[key];
|
List<Object?> get props => <Object?>[key];
|
||||||
@ -81,7 +85,7 @@ class SwipeGesturePreference extends BooleanPreference {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get subtitle =>
|
String get subtitle =>
|
||||||
'''Enable swipe gesture for switching between tabs. If enabled, long press on Story tile to trigger the action menu.''';
|
'''enable swipe gesture for switching between tabs. If enabled, long press on Story tile to trigger the action menu.''';
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotificationModePreference extends BooleanPreference {
|
class NotificationModePreference extends BooleanPreference {
|
||||||
@ -118,6 +122,10 @@ class CollapseModePreference extends BooleanPreference {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => 'Tap Anywhere to Collapse';
|
String get title => 'Tap Anywhere to Collapse';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get subtitle =>
|
||||||
|
'''if disabled, tap on the top of comment tile to collapse.''';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The value deciding whether or not the story
|
/// The value deciding whether or not the story
|
||||||
|
@ -1,41 +1,6 @@
|
|||||||
import 'package:hacki/config/constants.dart';
|
import 'package:hacki/config/constants.dart';
|
||||||
import 'package:hacki/models/item.dart';
|
import 'package:hacki/models/item.dart';
|
||||||
|
|
||||||
enum StoryType {
|
|
||||||
top('topstories'),
|
|
||||||
best('beststories'),
|
|
||||||
latest('newstories'),
|
|
||||||
ask('askstories'),
|
|
||||||
show('showstories');
|
|
||||||
|
|
||||||
const StoryType(this.path);
|
|
||||||
|
|
||||||
final String path;
|
|
||||||
|
|
||||||
String get label {
|
|
||||||
switch (this) {
|
|
||||||
case StoryType.top:
|
|
||||||
return 'TOP';
|
|
||||||
case StoryType.best:
|
|
||||||
return 'BEST';
|
|
||||||
case StoryType.latest:
|
|
||||||
return 'NEW';
|
|
||||||
case StoryType.ask:
|
|
||||||
return 'ASK';
|
|
||||||
case StoryType.show:
|
|
||||||
return 'SHOW';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int convertToSettingsValue(List<StoryType> tabs) {
|
|
||||||
return int.parse(
|
|
||||||
tabs
|
|
||||||
.map((StoryType e) => e.index.toString())
|
|
||||||
.reduce((String value, String element) => '$value$element'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Story extends Item {
|
class Story extends Item {
|
||||||
const Story({
|
const Story({
|
||||||
required super.descendants,
|
required super.descendants,
|
||||||
@ -55,23 +20,7 @@ class Story extends Item {
|
|||||||
parent: 0,
|
parent: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Story.empty()
|
Story.empty() : super.empty();
|
||||||
: super(
|
|
||||||
id: 0,
|
|
||||||
score: 0,
|
|
||||||
descendants: 0,
|
|
||||||
time: 0,
|
|
||||||
by: '',
|
|
||||||
title: '',
|
|
||||||
url: '',
|
|
||||||
kids: <int>[],
|
|
||||||
dead: false,
|
|
||||||
parts: <int>[],
|
|
||||||
deleted: false,
|
|
||||||
parent: 0,
|
|
||||||
text: '',
|
|
||||||
type: '',
|
|
||||||
);
|
|
||||||
|
|
||||||
Story.placeholder()
|
Story.placeholder()
|
||||||
: super(
|
: super(
|
||||||
|
34
lib/models/story_type.dart
Normal file
34
lib/models/story_type.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
enum StoryType {
|
||||||
|
top('topstories'),
|
||||||
|
best('beststories'),
|
||||||
|
latest('newstories'),
|
||||||
|
ask('askstories'),
|
||||||
|
show('showstories');
|
||||||
|
|
||||||
|
const StoryType(this.path);
|
||||||
|
|
||||||
|
final String path;
|
||||||
|
|
||||||
|
String get label {
|
||||||
|
switch (this) {
|
||||||
|
case StoryType.top:
|
||||||
|
return 'TOP';
|
||||||
|
case StoryType.best:
|
||||||
|
return 'BEST';
|
||||||
|
case StoryType.latest:
|
||||||
|
return 'NEW';
|
||||||
|
case StoryType.ask:
|
||||||
|
return 'ASK';
|
||||||
|
case StoryType.show:
|
||||||
|
return 'SHOW';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int convertToSettingsValue(List<StoryType> tabs) {
|
||||||
|
return int.parse(
|
||||||
|
tabs
|
||||||
|
.map((StoryType e) => e.index.toString())
|
||||||
|
.reduce((String value, String element) => '$value$element'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1358,5 +1358,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.18.0 <4.0.0"
|
dart: ">=2.18.0 <3.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.7.1"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
name: hacki
|
name: hacki
|
||||||
description: A Hacker News reader.
|
description: A Hacker News reader.
|
||||||
version: 1.0.5+83
|
version: 1.0.8+86
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
flutter: "3.7.0"
|
flutter: "3.7.2"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
adaptive_theme: ^3.0.0
|
adaptive_theme: ^3.0.0
|
||||||
|
Submodule submodules/flutter updated: b06b8b2710...32fb2f948e
Reference in New Issue
Block a user