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

リアルタイム通知画面のサンプル実装 #11

Merged
merged 6 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion lib/debug/debug_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -41,6 +42,12 @@ class _DebugPageState extends State<DebugPage> {
body: ListView(
padding: EdgeInsets.symmetric(horizontal: 16.w),
children: [
_button("通知画面", onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const SignInPage()),
);
}),
_button(
'サインイン画面',
onPressed: () {
Expand All @@ -53,7 +60,6 @@ class _DebugPageState extends State<DebugPage> {
},
),
_button('タイムライン画面', onPressed: () {}),
_button('通知画面', onPressed: () {}),
_button(
'searchBar',
onPressed: () {
Expand Down
142 changes: 142 additions & 0 deletions lib/debug/debug_real_time_notification_page.dart
Original file line number Diff line number Diff line change
@@ -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<SignInPage> createState() => _SignInPageState();
}

class _SignInPageState extends State<SignInPage> {
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<DebugRealTimeNotificationPage> createState() =>
_DebugRealTimeNotificationPageState();
}

class _DebugRealTimeNotificationPageState
extends State<DebugRealTimeNotificationPage> {
List<String> 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<String, dynamic> body = json.decode(data);
Map<String, dynamic> payloadData = json.decode(body["payload"]);
if (mounted) {
setState(() {
nameList.add(payloadData['account']['username']);
});
}
});
Comment on lines +97 to +110
Copy link
Collaborator

Choose a reason for hiding this comment

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

天才か!?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yoくんでもできるよ笑笑

}

@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),
);
}
}
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading