diff --git a/lib/debug/debug_page.dart b/lib/debug/debug_page.dart index df2ef37..19f63d3 100644 --- a/lib/debug/debug_page.dart +++ b/lib/debug/debug_page.dart @@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:pg_mobile/debug/debug_follow_list_page.dart'; import 'package:pg_mobile/debug/debug_follower_list_page.dart'; import 'package:pg_mobile/debug/debug_pgn_page.dart'; +import 'package:pg_mobile/debug/debug_real_time_notification_page.dart'; import 'package:pg_mobile/debug/debug_search_bar_page.dart'; import 'package:pg_mobile/debug/debug_text_theme_page.dart'; import 'package:pg_mobile/debug/login_sample/login_sample.dart'; @@ -41,6 +42,12 @@ class _DebugPageState extends State { body: ListView( padding: EdgeInsets.symmetric(horizontal: 16.w), children: [ + _button("通知画面", onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (_) => const SignInPage()), + ); + }), _button( 'サインイン画面', onPressed: () { @@ -53,7 +60,6 @@ class _DebugPageState extends State { }, ), _button('タイムライン画面', onPressed: () {}), - _button('通知画面', onPressed: () {}), _button( 'searchBar', onPressed: () { diff --git a/lib/debug/debug_real_time_notification_page.dart b/lib/debug/debug_real_time_notification_page.dart new file mode 100644 index 0000000..2122d83 --- /dev/null +++ b/lib/debug/debug_real_time_notification_page.dart @@ -0,0 +1,142 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:pg_mobile/repository/mastodon_repository.dart'; +import 'package:web_socket_channel/io.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class SignInPage extends StatefulWidget { + const SignInPage({Key? key}) : super(key: key); + + @override + State createState() => _SignInPageState(); +} + +class _SignInPageState extends State { + late final WebViewController controller; + @override + void initState() { + super.initState(); + controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..loadRequest(Uri.parse(MastodonRepository.instance.url)) + ..setNavigationDelegate( + NavigationDelegate( + onPageFinished: (String url) async { + final uri = Uri.parse(url); + if (uri.queryParameters['code'] != null) { + final accessToken = await MastodonRepository.instance.signIn(uri); + if (accessToken != null) { + if (!mounted) return; + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + DebugRealTimeNotificationPage(accessToken: accessToken), + ), + ); + } + } + }, + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("サインイン"), + centerTitle: true, + ), + body: Center( + child: ElevatedButton( + onPressed: () { + showModalBottomSheet( + isScrollControlled: true, + enableDrag: true, + backgroundColor: Colors.transparent, + context: context, + builder: (BuildContext context) { + return SizedBox( + height: MediaQuery.of(context).size.height * 0.75, + child: LoginView( + controller: controller, + ), + ); + }, + ); + }, + child: const Text("サインインする"), + ), + ), + ); + } +} + +class DebugRealTimeNotificationPage extends StatefulWidget { + final String accessToken; + + const DebugRealTimeNotificationPage({Key? key, required this.accessToken}) + : super(key: key); + + @override + State createState() => + _DebugRealTimeNotificationPageState(); +} + +class _DebugRealTimeNotificationPageState + extends State { + List nameList = []; + late final WebSocketChannel channel; + @override + void initState() { + super.initState(); + // WebSocketの接続を行う + channel = IOWebSocketChannel.connect( + Uri.parse( + "wss://community.4nonome.com/api/v1/streaming/?stream=user:notification&access_token=${widget.accessToken}"), + ); + // リアルタイムで返ってきた通知を処理する + channel.stream.listen((data) { + Map body = json.decode(data); + Map payloadData = json.decode(body["payload"]); + if (mounted) { + setState(() { + nameList.add(payloadData['account']['username']); + }); + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("通知リスト"), + centerTitle: true, + ), + body: ListView.builder( + itemCount: nameList.length, + itemBuilder: (BuildContext context, int index) { + return Text(nameList[index]); + }, + ), + ); + } +} + +class LoginView extends StatelessWidget { + final WebViewController controller; + const LoginView({Key? key, required this.controller}) : super(key: key); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Login"), + ), + body: WebViewWidget(controller: controller), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 273cfda..85d5926 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,13 +39,13 @@ dependencies: modal_bottom_sheet: ^3.0.0-pre flutter_screenutil: ^5.9.0 envied: ^0.5.3 + webview_flutter: ^4.7.0 + web_socket_channel: ^2.4.0 freezed_annotation: ^2.4.1 json_annotation: ^4.8.1 dio: ^5.4.1 - webview_flutter: ^4.5.0 firebase_core: ^2.24.2 cloud_firestore: ^4.14.0 - http: ^1.1.0 intl: ^0.19.0 dev_dependencies: