mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
58139ba7a3 | |||
33a31acbe2 | |||
0fcfcbb7e3 | |||
a98f52c90b | |||
8e8e48c44a | |||
603b7cc939 | |||
649fa33df3 | |||
81d4a0f2df | |||
24112a471e | |||
c7824eaef3 |
18
.github/workflows/commit_check.yml
vendored
18
.github/workflows/commit_check.yml
vendored
@ -11,15 +11,13 @@ jobs:
|
|||||||
name: Check commit
|
name: Check commit
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
env:
|
|
||||||
FLUTTER_VERSION: "3.7.1"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: checkout all the submodules
|
||||||
- uses: subosito/flutter-action@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
flutter-version: '3.7.1'
|
submodules: recursive
|
||||||
channel: 'stable'
|
- run: submodules/flutter/bin/flutter doctor
|
||||||
- run: flutter pub get
|
- run: submodules/flutter/bin/flutter pub get
|
||||||
- run: flutter format --set-exit-if-changed .
|
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
||||||
- run: flutter analyze
|
- run: submodules/flutter/bin/flutter analyze lib test integration_test
|
||||||
- run: flutter test
|
- run: submodules/flutter/bin/flutter test
|
23
.github/workflows/publish_ios.yml
vendored
23
.github/workflows/publish_ios.yml
vendored
@ -20,21 +20,21 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out from git
|
- name: Check out from git
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- run: submodules/flutter/bin/flutter doctor
|
||||||
|
- run: submodules/flutter/bin/flutter pub get
|
||||||
|
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
||||||
|
- run: submodules/flutter/bin/flutter analyze lib test integration_test
|
||||||
|
- run: submodules/flutter/bin/flutter test
|
||||||
|
|
||||||
# Configure ruby according to our .ruby-version
|
# Configure ruby according to our .ruby-version
|
||||||
- name: Setup ruby & Bundler
|
- name: Setup ruby & Bundler
|
||||||
uses: ruby/setup-ruby@v1
|
uses: ruby/setup-ruby@v1
|
||||||
with:
|
with:
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
# Set up flutter (feel free to adjust the version below)
|
|
||||||
- name: Setup flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
cache: true
|
|
||||||
flutter-version: 3.7.1
|
|
||||||
- run: flutter pub get
|
|
||||||
- run: flutter format --set-exit-if-changed .
|
|
||||||
- run: flutter analyze
|
|
||||||
# Start an ssh-agent that will provide the SSH key from the
|
# Start an ssh-agent that will provide the SSH key from the
|
||||||
# SSH_PRIVATE_KEY secret to `fastlane match`
|
# SSH_PRIVATE_KEY secret to `fastlane match`
|
||||||
- name: Setup SSH key
|
- name: Setup SSH key
|
||||||
@ -43,8 +43,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
||||||
ssh-add - <<< "${{ secrets.SSH_PRIVATE_KEY }}"
|
ssh-add - <<< "${{ secrets.SSH_PRIVATE_KEY }}"
|
||||||
- name: Download dependencies
|
|
||||||
run: flutter pub get
|
|
||||||
- name: Build & Publish to TestFlight with Fastlane
|
- name: Build & Publish to TestFlight with Fastlane
|
||||||
env:
|
env:
|
||||||
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
|
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
|
||||||
|
@ -49,7 +49,7 @@ latest_testflight_build_number
|
|||||||
|
|
||||||
# Prep the xcodeproject from Flutter without building (`--config-only`)
|
# Prep the xcodeproject from Flutter without building (`--config-only`)
|
||||||
sh(
|
sh(
|
||||||
"flutter", "build", "ios", "--config-only",
|
"/Users/runner/work/Hacki/Hacki/submodules/flutter/bin/flutter", "build", "ios", "--config-only",
|
||||||
"--release", "--no-pub", "--no-codesign",
|
"--release", "--no-pub", "--no-codesign",
|
||||||
"--build-number", new_build_number.to_s
|
"--build-number", new_build_number.to_s
|
||||||
)
|
)
|
||||||
|
@ -56,6 +56,8 @@ abstract class Constants {
|
|||||||
'ʕ•́ᴥ•̀ʔっ',
|
'ʕ•́ᴥ•̀ʔっ',
|
||||||
'(ㆆ_ㆆ)',
|
'(ㆆ_ㆆ)',
|
||||||
].pickRandomly()!;
|
].pickRandomly()!;
|
||||||
|
|
||||||
|
static final String errorMessage = 'Something went wrong...$sadFace';
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RegExpConstants {
|
abstract class RegExpConstants {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hacki/config/constants.dart';
|
||||||
import 'package:hacki/screens/screens.dart';
|
import 'package:hacki/screens/screens.dart';
|
||||||
|
|
||||||
/// Custom router.
|
/// Custom router.
|
||||||
@ -39,8 +40,8 @@ class CustomRouter {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Error'),
|
title: const Text('Error'),
|
||||||
),
|
),
|
||||||
body: const Center(
|
body: Center(
|
||||||
child: Text('Something went wrong!'),
|
child: Text(Constants.errorMessage),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -20,7 +20,7 @@ Future<void> setUpLocator() async {
|
|||||||
Logger(
|
Logger(
|
||||||
filter: CustomLogFilter(),
|
filter: CustomLogFilter(),
|
||||||
printer: LogUtil.logPrinter,
|
printer: LogUtil.logPrinter,
|
||||||
output: LogUtil.getLogOutput(logOutputFile),
|
output: LogUtil.logOutput(logOutputFile),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
..registerSingleton<StoriesRepository>(StoriesRepository())
|
..registerSingleton<StoriesRepository>(StoriesRepository())
|
||||||
|
@ -2,6 +2,8 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:hacki/config/constants.dart';
|
||||||
|
import 'package:hacki/styles/styles.dart';
|
||||||
|
|
||||||
extension ContextExtension on BuildContext {
|
extension ContextExtension on BuildContext {
|
||||||
T? tryRead<T>() {
|
T? tryRead<T>() {
|
||||||
@ -12,6 +14,31 @@ extension ContextExtension on BuildContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showSnackBar({
|
||||||
|
required String content,
|
||||||
|
VoidCallback? action,
|
||||||
|
String? label,
|
||||||
|
}) {
|
||||||
|
ScaffoldMessenger.of(this).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: Palette.deepOrange,
|
||||||
|
content: Text(content),
|
||||||
|
action: action != null && label != null
|
||||||
|
? SnackBarAction(
|
||||||
|
label: label,
|
||||||
|
onPressed: action,
|
||||||
|
textColor: Theme.of(this).textTheme.bodyLarge?.color,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showErrorSnackBar() => showSnackBar(
|
||||||
|
content: Constants.errorMessage,
|
||||||
|
);
|
||||||
|
|
||||||
Rect? get rect {
|
Rect? get rect {
|
||||||
final RenderBox? box = findRenderObject() as RenderBox?;
|
final RenderBox? box = findRenderObject() as RenderBox?;
|
||||||
final Rect? rect =
|
final Rect? rect =
|
||||||
|
@ -21,22 +21,15 @@ extension StateExtension on State {
|
|||||||
VoidCallback? action,
|
VoidCallback? action,
|
||||||
String? label,
|
String? label,
|
||||||
}) {
|
}) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
context.showSnackBar(
|
||||||
SnackBar(
|
content: content,
|
||||||
backgroundColor: Palette.deepOrange,
|
action: action,
|
||||||
content: Text(content),
|
|
||||||
action: action != null && label != null
|
|
||||||
? SnackBarAction(
|
|
||||||
label: label,
|
label: label,
|
||||||
onPressed: action,
|
|
||||||
textColor: Theme.of(context).textTheme.bodyLarge?.color,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showErrorSnackBar() => context.showErrorSnackBar();
|
||||||
|
|
||||||
Future<void>? goToItemScreen({
|
Future<void>? goToItemScreen({
|
||||||
required ItemScreenArgs args,
|
required ItemScreenArgs args,
|
||||||
bool forceNewScreen = false,
|
bool forceNewScreen = false,
|
||||||
@ -70,7 +63,6 @@ extension StateExtension on State {
|
|||||||
return MorePopupMenu(
|
return MorePopupMenu(
|
||||||
item: item,
|
item: item,
|
||||||
isBlocked: isBlocked,
|
isBlocked: isBlocked,
|
||||||
showSnackBar: showSnackBar,
|
|
||||||
onStoryLinkTapped: onStoryLinkTapped,
|
onStoryLinkTapped: onStoryLinkTapped,
|
||||||
onLoginTapped: onLoginTapped,
|
onLoginTapped: onLoginTapped,
|
||||||
);
|
);
|
||||||
|
@ -301,7 +301,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
.fetchStoryBy(storyId)
|
.fetchStoryBy(storyId)
|
||||||
.then((Story? story) {
|
.then((Story? story) {
|
||||||
if (story == null) {
|
if (story == null) {
|
||||||
showSnackBar(content: 'Something went wrong...');
|
showErrorSnackBar();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
||||||
@ -326,7 +326,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
.fetchStoryBy(storyId)
|
.fetchStoryBy(storyId)
|
||||||
.then((Story? story) {
|
.then((Story? story) {
|
||||||
if (story == null) {
|
if (story == null) {
|
||||||
showSnackBar(content: 'Something went wrong...');
|
showErrorSnackBar();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
||||||
|
@ -239,12 +239,7 @@ class _ItemScreenState extends State<ItemScreen> with RouteAware {
|
|||||||
context.read<EditCubit>().onReplySubmittedSuccessfully();
|
context.read<EditCubit>().onReplySubmittedSuccessfully();
|
||||||
context.read<PostCubit>().reset();
|
context.read<PostCubit>().reset();
|
||||||
} else if (postState.status == PostStatus.failure) {
|
} else if (postState.status == PostStatus.failure) {
|
||||||
showSnackBar(
|
showErrorSnackBar();
|
||||||
content: 'Something went wrong...'
|
|
||||||
'${Constants.sadFace}',
|
|
||||||
label: 'Okay',
|
|
||||||
action: ScaffoldMessenger.of(context).hideCurrentSnackBar,
|
|
||||||
);
|
|
||||||
context.read<PostCubit>().reset();
|
context.read<PostCubit>().reset();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -87,13 +87,13 @@ class LoginDialog extends StatelessWidget {
|
|||||||
height: Dimens.pt16,
|
height: Dimens.pt16,
|
||||||
),
|
),
|
||||||
if (state.status == AuthStatus.failure)
|
if (state.status == AuthStatus.failure)
|
||||||
const Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: Dimens.pt18,
|
left: Dimens.pt18,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Something went wrong...',
|
Constants.errorMessage,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
color: Palette.grey,
|
color: Palette.grey,
|
||||||
fontSize: TextDimens.pt12,
|
fontSize: TextDimens.pt12,
|
||||||
),
|
),
|
||||||
|
@ -15,18 +15,12 @@ class MorePopupMenu extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.item,
|
required this.item,
|
||||||
required this.isBlocked,
|
required this.isBlocked,
|
||||||
required this.showSnackBar,
|
|
||||||
required this.onStoryLinkTapped,
|
required this.onStoryLinkTapped,
|
||||||
required this.onLoginTapped,
|
required this.onLoginTapped,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Item item;
|
final Item item;
|
||||||
final bool isBlocked;
|
final bool isBlocked;
|
||||||
final void Function({
|
|
||||||
required String content,
|
|
||||||
VoidCallback? action,
|
|
||||||
String? label,
|
|
||||||
}) showSnackBar;
|
|
||||||
final ValueChanged<String> onStoryLinkTapped;
|
final ValueChanged<String> onStoryLinkTapped;
|
||||||
final VoidCallback onLoginTapped;
|
final VoidCallback onLoginTapped;
|
||||||
|
|
||||||
@ -43,24 +37,26 @@ class MorePopupMenu extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
listener: (BuildContext context, VoteState voteState) {
|
listener: (BuildContext context, VoteState voteState) {
|
||||||
if (voteState.status == VoteStatus.submitted) {
|
if (voteState.status == VoteStatus.submitted) {
|
||||||
showSnackBar(content: 'Vote submitted successfully.');
|
context.showSnackBar(content: 'Vote submitted successfully.');
|
||||||
} else if (voteState.status == VoteStatus.canceled) {
|
} else if (voteState.status == VoteStatus.canceled) {
|
||||||
showSnackBar(content: 'Vote canceled.');
|
context.showSnackBar(content: 'Vote canceled.');
|
||||||
} else if (voteState.status == VoteStatus.failure) {
|
} else if (voteState.status == VoteStatus.failure) {
|
||||||
showSnackBar(content: 'Something went wrong...');
|
context.showErrorSnackBar();
|
||||||
} else if (voteState.status ==
|
} else if (voteState.status ==
|
||||||
VoteStatus.failureKarmaBelowThreshold) {
|
VoteStatus.failureKarmaBelowThreshold) {
|
||||||
showSnackBar(
|
context.showSnackBar(
|
||||||
content: "You can't downvote because you are karmaly broke.",
|
content: "You can't downvote because you are karmaly broke.",
|
||||||
);
|
);
|
||||||
} else if (voteState.status == VoteStatus.failureNotLoggedIn) {
|
} else if (voteState.status == VoteStatus.failureNotLoggedIn) {
|
||||||
showSnackBar(
|
context.showSnackBar(
|
||||||
content: 'Not logged in, no voting! (;`O´)o',
|
content: 'Not logged in, no voting! (;`O´)o',
|
||||||
action: onLoginTapped,
|
action: onLoginTapped,
|
||||||
label: 'Log in',
|
label: 'Log in',
|
||||||
);
|
);
|
||||||
} else if (voteState.status == VoteStatus.failureBeHumble) {
|
} else if (voteState.status == VoteStatus.failureBeHumble) {
|
||||||
showSnackBar(content: 'No voting on your own post! (;`O´)o');
|
context.showSnackBar(
|
||||||
|
content: 'No voting on your own post! (;`O´)o',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_fadein/flutter_fadein.dart';
|
import 'package:flutter_fadein/flutter_fadein.dart';
|
||||||
import 'package:hacki/blocs/auth/auth_bloc.dart';
|
import 'package:hacki/blocs/auth/auth_bloc.dart';
|
||||||
import 'package:hacki/cubits/cubits.dart';
|
import 'package:hacki/cubits/cubits.dart';
|
||||||
|
import 'package:hacki/extensions/context_extension.dart';
|
||||||
import 'package:hacki/models/models.dart';
|
import 'package:hacki/models/models.dart';
|
||||||
import 'package:hacki/styles/styles.dart';
|
import 'package:hacki/styles/styles.dart';
|
||||||
|
|
||||||
@ -66,23 +67,18 @@ class PollView extends StatelessWidget {
|
|||||||
content: 'Vote submitted successfully.',
|
content: 'Vote submitted successfully.',
|
||||||
);
|
);
|
||||||
} else if (voteState.status == VoteStatus.canceled) {
|
} else if (voteState.status == VoteStatus.canceled) {
|
||||||
showSnackBar(context, content: 'Vote canceled.');
|
context.showSnackBar(content: 'Vote canceled.');
|
||||||
} else if (voteState.status == VoteStatus.failure) {
|
} else if (voteState.status == VoteStatus.failure) {
|
||||||
showSnackBar(
|
context.showErrorSnackBar();
|
||||||
context,
|
|
||||||
content: 'Something went wrong...',
|
|
||||||
);
|
|
||||||
} else if (voteState.status ==
|
} else if (voteState.status ==
|
||||||
VoteStatus.failureKarmaBelowThreshold) {
|
VoteStatus.failureKarmaBelowThreshold) {
|
||||||
showSnackBar(
|
context.showSnackBar(
|
||||||
context,
|
|
||||||
content: "You can't downvote because"
|
content: "You can't downvote because"
|
||||||
' you are karmaly broke.',
|
' you are karmaly broke.',
|
||||||
);
|
);
|
||||||
} else if (voteState.status ==
|
} else if (voteState.status ==
|
||||||
VoteStatus.failureNotLoggedIn) {
|
VoteStatus.failureNotLoggedIn) {
|
||||||
showSnackBar(
|
context.showSnackBar(
|
||||||
context,
|
|
||||||
content: 'Not logged in, no voting! (;`O´)o',
|
content: 'Not logged in, no voting! (;`O´)o',
|
||||||
action: onLoginTapped,
|
action: onLoginTapped,
|
||||||
label: 'Log in',
|
label: 'Log in',
|
||||||
|
@ -453,13 +453,13 @@ class _ProfileScreenState extends State<ProfileScreen>
|
|||||||
height: Dimens.pt16,
|
height: Dimens.pt16,
|
||||||
),
|
),
|
||||||
if (state.status == AuthStatus.failure)
|
if (state.status == AuthStatus.failure)
|
||||||
const Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: Dimens.pt18,
|
left: Dimens.pt18,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Something went wrong...',
|
Constants.errorMessage,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
color: Palette.grey,
|
color: Palette.grey,
|
||||||
fontSize: TextDimens.pt12,
|
fontSize: TextDimens.pt12,
|
||||||
),
|
),
|
||||||
|
@ -50,9 +50,7 @@ class _SubmitScreenState extends State<SubmitScreen> {
|
|||||||
content: 'Post submitted successfully.',
|
content: 'Post submitted successfully.',
|
||||||
);
|
);
|
||||||
} else if (state.status == SubmitStatus.failure) {
|
} else if (state.status == SubmitStatus.failure) {
|
||||||
showSnackBar(
|
showErrorSnackBar();
|
||||||
content: 'Something went wrong...',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
builder: (BuildContext context, SubmitState state) {
|
builder: (BuildContext context, SubmitState state) {
|
||||||
|
@ -157,6 +157,11 @@ class CommentTile extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
AnimatedSize(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
if (actionable && state.collapsed)
|
if (actionable && state.collapsed)
|
||||||
Center(
|
Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@ -200,7 +205,8 @@ class CommentTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else if (blocklistState.blocklist.contains(comment.by))
|
else if (blocklistState.blocklist
|
||||||
|
.contains(comment.by))
|
||||||
const Center(
|
const Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
@ -226,7 +232,8 @@ class CommentTile extends StatelessWidget {
|
|||||||
? SelectableText.rich(
|
? SelectableText.rich(
|
||||||
key: ValueKey<int>(comment.id),
|
key: ValueKey<int>(comment.id),
|
||||||
buildTextSpan(
|
buildTextSpan(
|
||||||
(comment as BuildableComment).elements,
|
(comment as BuildableComment)
|
||||||
|
.elements,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: MediaQuery.of(
|
fontSize: MediaQuery.of(
|
||||||
context,
|
context,
|
||||||
@ -238,12 +245,14 @@ class CommentTile extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
).textScaleFactor *
|
).textScaleFactor *
|
||||||
prefState.fontSize.fontSize,
|
prefState.fontSize.fontSize,
|
||||||
decoration: TextDecoration.underline,
|
decoration:
|
||||||
|
TextDecoration.underline,
|
||||||
color: Palette.orange,
|
color: Palette.orange,
|
||||||
),
|
),
|
||||||
onOpen: (LinkableElement link) {
|
onOpen: (LinkableElement link) {
|
||||||
if (link.url.isStoryLink) {
|
if (link.url.isStoryLink) {
|
||||||
onStoryLinkTapped.call(link.url);
|
onStoryLinkTapped
|
||||||
|
.call(link.url);
|
||||||
} else {
|
} else {
|
||||||
LinkUtil.launch(link.url);
|
LinkUtil.launch(link.url);
|
||||||
}
|
}
|
||||||
@ -293,13 +302,16 @@ class CommentTile extends StatelessWidget {
|
|||||||
horizontal: Dimens.pt12,
|
horizontal: Dimens.pt12,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
HapticFeedback.selectionClick();
|
HapticFeedback.selectionClick();
|
||||||
context.read<CommentsCubit>().loadMore(
|
context
|
||||||
|
.read<CommentsCubit>()
|
||||||
|
.loadMore(
|
||||||
comment: comment,
|
comment: comment,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -320,6 +332,9 @@ class CommentTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -111,7 +111,7 @@ class _CountDownReminderState extends State<CountdownReminder>
|
|||||||
.fetchStoryBy(state.storyId!)
|
.fetchStoryBy(state.storyId!)
|
||||||
.then((Story? story) {
|
.then((Story? story) {
|
||||||
if (story == null) {
|
if (story == null) {
|
||||||
showSnackBar(content: 'Something went wrong...');
|
showErrorSnackBar();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
final ItemScreenArgs args = ItemScreenArgs(item: story);
|
||||||
|
@ -5,7 +5,7 @@ import 'package:hacki/config/constants.dart';
|
|||||||
import 'package:hacki/extensions/extensions.dart';
|
import 'package:hacki/extensions/extensions.dart';
|
||||||
import 'package:hacki/models/models.dart';
|
import 'package:hacki/models/models.dart';
|
||||||
import 'package:hacki/screens/widgets/link_preview/link_view.dart';
|
import 'package:hacki/screens/widgets/link_preview/link_view.dart';
|
||||||
import 'package:hacki/screens/widgets/link_preview/web_analyzer.dart';
|
import 'package:hacki/services/services.dart';
|
||||||
import 'package:hacki/styles/styles.dart';
|
import 'package:hacki/styles/styles.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ class _LinkPreviewState extends State<LinkPreview> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_errorTitle = widget.errorTitle ?? 'Something went wrong!';
|
_errorTitle = widget.errorTitle ?? Constants.errorMessage;
|
||||||
_errorBody = widget.errorBody ??
|
_errorBody = widget.errorBody ??
|
||||||
'Oops! Unable to parse the url. We have '
|
'Oops! Unable to parse the url. We have '
|
||||||
'sent feedback to our developers & '
|
'sent feedback to our developers & '
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:hacki/blocs/blocs.dart';
|
import 'package:hacki/blocs/blocs.dart';
|
||||||
import 'package:hacki/cubits/cubits.dart';
|
import 'package:hacki/cubits/cubits.dart';
|
||||||
import 'package:hacki/screens/widgets/link_preview/web_analyzer.dart';
|
import 'package:hacki/services/services.dart';
|
||||||
import 'package:hacki/styles/styles.dart';
|
import 'package:hacki/styles/styles.dart';
|
||||||
|
|
||||||
class OfflineBanner extends StatelessWidget {
|
class OfflineBanner extends StatelessWidget {
|
||||||
|
@ -3,3 +3,4 @@ export 'custom_bloc_observer.dart';
|
|||||||
export 'fetcher.dart';
|
export 'fetcher.dart';
|
||||||
export 'firebase_client.dart';
|
export 'firebase_client.dart';
|
||||||
export 'local_notification.dart';
|
export 'local_notification.dart';
|
||||||
|
export 'web_analyzer.dart';
|
||||||
|
@ -14,7 +14,7 @@ abstract class LogUtil {
|
|||||||
colors: false,
|
colors: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
static LogOutput getLogOutput(File outputFile) => MultiOutput(
|
static LogOutput logOutput(File outputFile) => MultiOutput(
|
||||||
<LogOutput>[
|
<LogOutput>[
|
||||||
ConsoleOutput(),
|
ConsoleOutput(),
|
||||||
CustomFileOutput(
|
CustomFileOutput(
|
||||||
@ -43,7 +43,7 @@ abstract class LogUtil {
|
|||||||
|
|
||||||
final Uint8List fileContent = await currentSessionLog.readAsBytes();
|
final Uint8List fileContent = await currentSessionLog.readAsBytes();
|
||||||
await previousSessionLog.writeAsString(
|
await previousSessionLog.writeAsString(
|
||||||
'Current session logs:',
|
'Current session logs:\n',
|
||||||
mode: FileMode.append,
|
mode: FileMode.append,
|
||||||
);
|
);
|
||||||
return previousSessionLog.writeAsBytes(
|
return previousSessionLog.writeAsBytes(
|
||||||
|
@ -1359,4 +1359,4 @@ packages:
|
|||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.18.0 <3.0.0"
|
dart: ">=2.18.0 <3.0.0"
|
||||||
flutter: ">=3.7.1"
|
flutter: ">=3.7.3"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
name: hacki
|
name: hacki
|
||||||
description: A Hacker News reader.
|
description: A Hacker News reader.
|
||||||
version: 1.0.7+85
|
version: 1.0.9+87
|
||||||
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.1"
|
flutter: "3.7.3"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
adaptive_theme: ^3.0.0
|
adaptive_theme: ^3.0.0
|
||||||
|
Submodule submodules/flutter updated: 7048ed95a5...9944297138
Reference in New Issue
Block a user