Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter Webによるdocsビューワの作成 #299

Merged
merged 4 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/debug.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo-badge
マージする前に削除するの忘れないようにする

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Debug

# TODO: マージ前に消す

on:
push:
branches:
- docs-website

jobs:
debug:
runs-on: ubuntu-latest
steps:
# https://github.com/actions/checkout
- name: Fetch sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Remove unnecessary files
uses: ./.github/actions/remove-unnecessary-files

- name: Debug
run: |
git diff
43 changes: 43 additions & 0 deletions apps/website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
30 changes: 30 additions & 0 deletions apps/website/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
- platform: web
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
4 changes: 4 additions & 0 deletions apps/website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Website

This is a web document viewer.
You can view the markdown documents in the `docs/` directory by this app.
Comment on lines +3 to +4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good-badge
😍

6 changes: 6 additions & 0 deletions apps/website/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include: package:yumemi_lints/flutter/3.22/recommended.yaml

linter:
rules:
# Webを前提とするプロジェクトなので無効化
avoid_web_libraries_in_flutter: false
Comment on lines +5 to +6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good-badge
👍

1 change: 1 addition & 0 deletions apps/website/assets/docs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good-badge
このやり方いいですね✨

22 changes: 22 additions & 0 deletions apps/website/lib/hooks/use_markdown_doc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:website/utils/doc_key.dart';

String? useMarkdownDoc(String? docKey) {
final doc = useState<String?>(null);

useEffect(
() {
if (docKey != null) {
Future.microtask(() async {
doc.value = await rootBundle.loadString(toAssetKey(docKey));
});
}

return;
},
[docKey],
);

return doc.value;
}
27 changes: 27 additions & 0 deletions apps/website/lib/hooks/use_markdown_doc_keys.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:website/utils/doc_key.dart';

List<String> useMarkdownDocKeys() {
final docs = useState<List<String>>([]);

useEffect(
() {
Future.microtask(() async {
final manifest = await AssetManifest.loadFromAssetBundle(rootBundle);
final markdowns = manifest
.listAssets()
.where((key) => key.endsWith('.md'))
.map(toDocKey)
.toList();

docs.value = markdowns;
});

return;
},
[],
);

return docs.value;
}
22 changes: 22 additions & 0 deletions apps/website/lib/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:website/router/router.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Documents',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
routerConfig: router,
);
}
}
13 changes: 13 additions & 0 deletions apps/website/lib/router/router.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:website/ui/default_layout.dart';
import 'package:website/ui/markdown_page.dart';

part 'package:website/router/routes/markdown_page_route.dart';
part 'package:website/router/routes/markdown_shell_route.dart';
part 'router.g.dart';

final router = GoRouter(
initialLocation: '/',
routes: $appRoutes,
);
48 changes: 48 additions & 0 deletions apps/website/lib/router/router.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions apps/website/lib/router/routes/markdown_page_route.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
part of 'package:website/router/router.dart';

class MarkdownPageRoute extends GoRouteData {
const MarkdownPageRoute({
this.key,
});

static const path = '/';

final String? key;

@override
Widget build(BuildContext context, GoRouterState state) {
return MarkdownPage(docKey: key);
}
}
15 changes: 15 additions & 0 deletions apps/website/lib/router/routes/markdown_shell_route.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
part of 'package:website/router/router.dart';

@TypedShellRoute<MarkdownShellRoute>(
routes: [
TypedGoRoute<MarkdownPageRoute>(path: MarkdownPageRoute.path),
],
)
class MarkdownShellRoute extends ShellRouteData {
const MarkdownShellRoute();

@override
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
return DefaultLayout(child: navigator);
}
}
43 changes: 43 additions & 0 deletions apps/website/lib/ui/default_layout.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:website/hooks/use_markdown_doc_keys.dart';
import 'package:website/router/router.dart';

class DefaultLayout extends HookWidget {
const DefaultLayout({
required Widget child,
super.key,
}) : _navigator = child;

final Widget _navigator;

@override
Widget build(BuildContext context) {
final docKeys = useMarkdownDocKeys();

return Scaffold(
body: Row(
children: [
SizedBox(
width: 200,
child: ListView(
children: [
...docKeys.map(
(key) => ListTile(
title: Text(key),
onTap: () {
MarkdownPageRoute(key: key).go(context);
},
),
),
],
),
),
Expanded(
child: _navigator,
),
],
),
);
}
}
38 changes: 38 additions & 0 deletions apps/website/lib/ui/markdown_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'dart:js' as js;

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:website/hooks/use_markdown_doc.dart';

class MarkdownPage extends HookWidget {
const MarkdownPage({
required String? docKey,
super.key,
}) : _docKey = docKey;

final String? _docKey;

@override
Widget build(BuildContext context) {
final doc = useMarkdownDoc(_docKey);

if (doc == null) {
return const SizedBox.shrink();
}

return Markdown(
data: doc,
selectable: true,
onTapLink: (text, href, title) {
if (href == null) {
return;
}

// TODO: URLをみて、内部リンクの対応

js.context.callMethod('open', [href]);
},
);
}
}
9 changes: 9 additions & 0 deletions apps/website/lib/utils/doc_key.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const _prefix = 'assets/docs/';

String toDocKey(String assetKey) {
return assetKey.substring(_prefix.length);
}

String toAssetKey(String docKey) {
return '$_prefix$docKey';
}
Loading
Loading