MCSI-9 About and instruction tab #27
5
assets/svg/bug.svg
Normal file
5
assets/svg/bug.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M256 0c53 0 96 43 96 96l0 3.6c0 15.7-12.7 28.4-28.4 28.4l-135.1 0c-15.7 0-28.4-12.7-28.4-28.4l0-3.6c0-53 43-96 96-96zM41.4 105.4c12.5-12.5 32.8-12.5 45.3 0l64 64c.7 .7 1.3 1.4 1.9 2.1c14.2-7.3 30.4-11.4 47.5-11.4l112 0c17.1 0 33.2 4.1 47.5 11.4c.6-.7 1.2-1.4 1.9-2.1l64-64c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-64 64c-.7 .7-1.4 1.3-2.1 1.9c6.2 12 10.1 25.3 11.1 39.5l64.3 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-64 0c0 24.6-5.5 47.8-15.4 68.6c2.2 1.3 4.2 2.9 6 4.8l64 64c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-63.1-63.1c-24.5 21.8-55.8 36.2-90.3 39.6L272 240c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 239.2c-34.5-3.4-65.8-17.8-90.3-39.6L86.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l64-64c1.9-1.9 3.9-3.4 6-4.8C101.5 367.8 96 344.6 96 320l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64.3 0c1.1-14.1 5-27.5 11.1-39.5c-.7-.6-1.4-1.2-2.1-1.9l-64-64c-12.5-12.5-12.5-32.8 0-45.3z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
5
assets/svg/github.svg
Normal file
5
assets/svg/github.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 512">
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
5
assets/svg/send.svg
Normal file
5
assets/svg/send.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480l0-83.6c0-4 1.5-7.8 4.2-10.8L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" />
|
||||
</svg>
|
After Width: | Height: | Size: 582 B |
5
assets/svg/youtube.svg
Normal file
5
assets/svg/youtube.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M549.7 124.1c-6.3-23.7-24.8-42.3-48.3-48.6C458.8 64 288 64 288 64S117.2 64 74.6 75.5c-23.5 6.3-42 24.9-48.3 48.6-11.4 42.9-11.4 132.3-11.4 132.3s0 89.4 11.4 132.3c6.3 23.7 24.8 41.5 48.3 47.8C117.2 448 288 448 288 448s170.8 0 213.4-11.5c23.5-6.3 42-24.2 48.3-47.8 11.4-42.9 11.4-132.3 11.4-132.3s0-89.4-11.4-132.3zm-317.5 213.5V175.2l142.7 81.2-142.7 81.2z" />
|
||||
</svg>
|
After Width: | Height: | Size: 607 B |
130
lib/main/framework/ui/about_tab.dart
Normal file
130
lib/main/framework/ui/about_tab.dart
Normal file
@ -0,0 +1,130 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:minecraft_server_installer/main/constants.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
class AboutTab extends StatelessWidget {
|
||||
const AboutTab({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SizedBox(
|
||||
width: 460,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset('assets/img/mcsi_logo.png', width: 100, height: 100),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
Constants.appName,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineMedium
|
||||
?.copyWith(fontWeight: FontWeight.w900, color: Colors.blueGrey.shade900),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: PackageInfo.fromPlatform(),
|
||||
builder: (context, snapshot) => Text(
|
||||
'Version ${snapshot.data?.version ?? ''}',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey.shade700),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(32),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blueGrey.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border(left: BorderSide(color: Colors.blueGrey.shade300, width: 6)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: Icon(Icons.format_quote_rounded, color: Colors.grey.shade700),
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'讓 Minecraft 伺服器安裝變得更簡單!',
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Gap(32),
|
||||
Row(
|
||||
children: [
|
||||
_actionButton(text: '教學影片', svgAssetName: 'assets/svg/youtube.svg'),
|
||||
const Gap(12),
|
||||
_actionButton(text: '問題回報', svgAssetName: 'assets/svg/bug.svg'),
|
||||
const Gap(12),
|
||||
_actionButton(text: '聯絡作者', svgAssetName: 'assets/svg/send.svg'),
|
||||
const Gap(12),
|
||||
_actionButton(text: '原始碼', svgAssetName: 'assets/svg/github.svg'),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'Copyright © 2025 SquidSpirit',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey.shade700),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Widget _actionButton({
|
||||
required String text,
|
||||
required String svgAssetName,
|
||||
}) =>
|
||||
Builder(
|
||||
builder: (context) => Expanded(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.blueGrey.shade50, width: 2),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
svgAssetName,
|
||||
width: 32,
|
||||
height: 32,
|
||||
colorFilter: ColorFilter.mode(Colors.grey.shade800, BlendMode.srcIn),
|
||||
),
|
||||
const Gap(12),
|
||||
Text(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
@ -9,6 +9,7 @@ import 'package:minecraft_server_installer/main/application/use_case/write_file_
|
||||
import 'package:minecraft_server_installer/main/constants.dart';
|
||||
import 'package:minecraft_server_installer/main/framework/api/installation_api_service_impl.dart';
|
||||
import 'package:minecraft_server_installer/main/framework/storage/installation_file_storage_impl.dart';
|
||||
import 'package:minecraft_server_installer/main/framework/ui/about_tab.dart';
|
||||
import 'package:minecraft_server_installer/main/framework/ui/basic_configuration_tab.dart';
|
||||
import 'package:minecraft_server_installer/main/framework/ui/side_navigation_bar.dart';
|
||||
import 'package:minecraft_server_installer/vanilla/adapter/gateway/vanilla_repository_impl.dart';
|
||||
@ -100,8 +101,9 @@ class MinecraftServerInstaller extends StatelessWidget {
|
||||
return const BasicConfigurationTab();
|
||||
case NavigationItem.modConfiguration:
|
||||
case NavigationItem.serverProperties:
|
||||
case NavigationItem.about:
|
||||
return const Placeholder();
|
||||
case NavigationItem.about:
|
||||
return const AboutTab();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,9 @@ class SideNavigationBar extends StatefulWidget {
|
||||
|
||||
class _SideNavigationBarState extends State<SideNavigationBar> {
|
||||
bool _isExpanded = false;
|
||||
PackageInfo? _packageInfo;
|
||||
|
||||
double get width => _isExpanded ? 340 : 80;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
PackageInfo.fromPlatform().then((packageInfo) =>
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => setState(() => _packageInfo = packageInfo)));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
@ -50,10 +42,7 @@ class _SideNavigationBarState extends State<SideNavigationBar> {
|
||||
text: Constants.appName,
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: SizedBox.square(
|
||||
dimension: 32,
|
||||
child: Image.asset('assets/img/mcsi_logo.png', width: 2048, height: 2048),
|
||||
),
|
||||
child: Image.asset('assets/img/mcsi_logo.png', width: 32, height: 32),
|
||||
),
|
||||
padding: const EdgeInsets.only(left: 4),
|
||||
expandedKey: const ValueKey('expandedTitle'),
|
||||
@ -90,12 +79,15 @@ class _SideNavigationBarState extends State<SideNavigationBar> {
|
||||
const Gap(8),
|
||||
_navigationButton(NavigationItem.about),
|
||||
const Spacer(),
|
||||
_animatedText(
|
||||
text: 'Version ${_packageInfo?.version ?? ''}',
|
||||
padding: EdgeInsets.zero,
|
||||
expandedKey: const ValueKey('expandedVersion'),
|
||||
collapsedKey: const ValueKey('collapsedVersion'),
|
||||
alignment: Alignment.bottomCenter,
|
||||
FutureBuilder(
|
||||
future: PackageInfo.fromPlatform(),
|
||||
builder: (context, snapshot) => _animatedText(
|
||||
text: 'Version ${snapshot.data?.version ?? ''}',
|
||||
padding: EdgeInsets.zero,
|
||||
expandedKey: const ValueKey('expandedVersion'),
|
||||
collapsedKey: const ValueKey('collapsedVersion'),
|
||||
alignment: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -7,8 +7,8 @@ Future<void> main() async {
|
||||
await windowManager.ensureInitialized();
|
||||
|
||||
final windowOptions = const WindowOptions(
|
||||
size: Size(800, 600),
|
||||
minimumSize: Size(800, 600),
|
||||
size: Size(900, 600),
|
||||
minimumSize: Size(900, 600),
|
||||
center: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
skipTaskbar: false,
|
||||
|
@ -22,7 +22,7 @@ static void my_application_activate(GApplication* application) {
|
||||
|
||||
gtk_window_set_decorated(window, FALSE);
|
||||
|
||||
gtk_window_set_default_size(window, 800, 600);
|
||||
gtk_window_set_default_size(window, 900, 600);
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
|
64
pubspec.lock
64
pubspec.lock
@ -1,6 +1,14 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -126,6 +134,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.28"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: cd57f7969b4679317c17af6fd16ee233c1e60a82ed209d8a475c54fd6fd6f845
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -256,6 +272,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_parsing
|
||||
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -437,6 +469,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics
|
||||
sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.19"
|
||||
vector_graphics_codec:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_codec
|
||||
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.13"
|
||||
vector_graphics_compiler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: "557a315b7d2a6dbb0aaaff84d857967ce6bdc96a63dc6ee2a57ce5a6ee5d3331"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.17"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -477,6 +533,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
sdks:
|
||||
dart: ">=3.7.0 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
|
@ -37,6 +37,7 @@ dependencies:
|
||||
equatable: ^2.0.7
|
||||
file_picker: ^10.2.0
|
||||
flutter_bloc: ^9.1.1
|
||||
flutter_svg: ^2.2.0
|
||||
gap: ^3.0.1
|
||||
http: ^1.4.0
|
||||
package_info_plus: ^8.3.0
|
||||
@ -71,6 +72,7 @@ flutter:
|
||||
# - images/a_dot_ham.jpeg
|
||||
assets:
|
||||
- assets/img/
|
||||
- assets/svg/
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
Loading…
x
Reference in New Issue
Block a user