Use Telegram Login Widget for web auth
Some checks failed
Build and deploy Flutter Web / build (push) Has been cancelled
Some checks failed
Build and deploy Flutter Web / build (push) Has been cancelled
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
export 'telegram_init_data_stub.dart'
|
||||
if (dart.library.js_interop) 'telegram_init_data_web.dart';
|
||||
@@ -1 +0,0 @@
|
||||
String telegramInitData() => '';
|
||||
@@ -1,6 +0,0 @@
|
||||
import 'dart:js_interop';
|
||||
|
||||
@JS('window.Telegram.WebApp.initData')
|
||||
external JSString? get _telegramInitData;
|
||||
|
||||
String telegramInitData() => _telegramInitData?.toDart ?? '';
|
||||
@@ -1,2 +0,0 @@
|
||||
export 'telegram_launcher_stub.dart'
|
||||
if (dart.library.js_interop) 'telegram_launcher_web.dart';
|
||||
@@ -1 +0,0 @@
|
||||
void openTelegramUrl(String url) {}
|
||||
@@ -1,8 +0,0 @@
|
||||
import 'dart:js_interop';
|
||||
|
||||
@JS('window.open')
|
||||
external JSAny? _open(JSString url, JSString target, JSString features);
|
||||
|
||||
void openTelegramUrl(String url) {
|
||||
_open(url.toJS, '_blank'.toJS, 'noopener,noreferrer'.toJS);
|
||||
}
|
||||
2
lib/auth/telegram_login_button.dart
Normal file
2
lib/auth/telegram_login_button.dart
Normal file
@@ -0,0 +1,2 @@
|
||||
export 'telegram_login_button_stub.dart'
|
||||
if (dart.library.html) 'telegram_login_button_web.dart';
|
||||
12
lib/auth/telegram_login_button_stub.dart
Normal file
12
lib/auth/telegram_login_button_stub.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TelegramLoginButton extends StatelessWidget {
|
||||
const TelegramLoginButton({required this.onAuthenticated, super.key});
|
||||
|
||||
final VoidCallback onAuthenticated;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const FilledButton(onPressed: null, child: Text('Telegram'));
|
||||
}
|
||||
}
|
||||
76
lib/auth/telegram_login_button_web.dart
Normal file
76
lib/auth/telegram_login_button_web.dart
Normal file
@@ -0,0 +1,76 @@
|
||||
import 'dart:js_interop';
|
||||
import 'dart:js_interop_unsafe';
|
||||
import 'dart:ui_web' as ui_web;
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:web/web.dart' as web;
|
||||
|
||||
import 'telegram_session_web.dart';
|
||||
|
||||
const _telegramBotUsername = String.fromEnvironment(
|
||||
'TELEGRAM_BOT_USERNAME',
|
||||
defaultValue: 'carfteebot',
|
||||
);
|
||||
|
||||
@JS('window')
|
||||
external JSObject get _window;
|
||||
|
||||
class TelegramLoginButton extends StatefulWidget {
|
||||
const TelegramLoginButton({required this.onAuthenticated, super.key});
|
||||
|
||||
final VoidCallback onAuthenticated;
|
||||
|
||||
@override
|
||||
State<TelegramLoginButton> createState() => _TelegramLoginButtonState();
|
||||
}
|
||||
|
||||
class _TelegramLoginButtonState extends State<TelegramLoginButton> {
|
||||
late final String _callbackName =
|
||||
'mapflowTelegramAuth${DateTime.now().microsecondsSinceEpoch}';
|
||||
late final String _viewType = 'mapflow-telegram-login-$_callbackName';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final callback = ((JSAny? user) {
|
||||
saveTelegramLoginData(user);
|
||||
if (mounted) {
|
||||
widget.onAuthenticated();
|
||||
}
|
||||
}).toJS;
|
||||
_window.setProperty(_callbackName.toJS, callback);
|
||||
ui_web.platformViewRegistry.registerViewFactory(_viewType, _buildElement);
|
||||
}
|
||||
|
||||
web.HTMLElement _buildElement(int viewId) {
|
||||
final container = web.HTMLDivElement()
|
||||
..style.width = '100%'
|
||||
..style.height = '48px'
|
||||
..style.display = 'flex'
|
||||
..style.justifyContent = 'center'
|
||||
..style.alignItems = 'center';
|
||||
|
||||
final script = web.HTMLScriptElement()
|
||||
..src = 'https://telegram.org/js/telegram-widget.js?22'
|
||||
..async = true;
|
||||
|
||||
script
|
||||
..setAttribute('data-telegram-login', _telegramBotUsername)
|
||||
..setAttribute('data-size', 'large')
|
||||
..setAttribute('data-radius', '8')
|
||||
..setAttribute('data-userpic', 'false')
|
||||
..setAttribute('data-onauth', '$_callbackName(user)');
|
||||
|
||||
container.append(script);
|
||||
return container;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 48,
|
||||
width: 240,
|
||||
child: HtmlElementView(viewType: _viewType),
|
||||
);
|
||||
}
|
||||
}
|
||||
2
lib/auth/telegram_session.dart
Normal file
2
lib/auth/telegram_session.dart
Normal file
@@ -0,0 +1,2 @@
|
||||
export 'telegram_session_stub.dart'
|
||||
if (dart.library.html) 'telegram_session_web.dart';
|
||||
3
lib/auth/telegram_session_stub.dart
Normal file
3
lib/auth/telegram_session_stub.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
String telegramInitData() => '';
|
||||
|
||||
String telegramLoginData() => '';
|
||||
21
lib/auth/telegram_session_web.dart
Normal file
21
lib/auth/telegram_session_web.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'dart:js_interop';
|
||||
|
||||
import 'package:web/web.dart' as web;
|
||||
|
||||
const telegramLoginStorageKey = 'mapflow.telegramLoginData';
|
||||
|
||||
@JS('window.Telegram.WebApp.initData')
|
||||
external JSString? get _telegramInitData;
|
||||
|
||||
@JS('JSON.stringify')
|
||||
external JSString _jsonStringify(JSAny? value);
|
||||
|
||||
String telegramInitData() => _telegramInitData?.toDart ?? '';
|
||||
|
||||
String telegramLoginData() =>
|
||||
web.window.localStorage.getItem(telegramLoginStorageKey) ?? '';
|
||||
|
||||
void saveTelegramLoginData(JSAny? user) {
|
||||
final encoded = _jsonStringify(user).toDart;
|
||||
web.window.localStorage.setItem(telegramLoginStorageKey, encoded);
|
||||
}
|
||||
Reference in New Issue
Block a user