✨ Sign in & Sign up redirection
This commit is contained in:
202
lib/screens/account.dart
Normal file
202
lib/screens/account.dart
Normal file
@ -0,0 +1,202 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:solian/utils/service_url.dart';
|
||||
import 'package:solian/widgets/wrapper.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class AccountScreen extends StatefulWidget {
|
||||
const AccountScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AccountScreen> createState() => _AccountScreenState();
|
||||
}
|
||||
|
||||
class _AccountScreenState extends State<AccountScreen> {
|
||||
bool isAuthorized = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () async {
|
||||
var authorized = await context.read<AuthProvider>().isAuthorized();
|
||||
setState(() => isAuthorized = authorized);
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = context.watch<AuthProvider>();
|
||||
|
||||
return LayoutWrapper(
|
||||
title: AppLocalizations.of(context)!.account,
|
||||
child: isAuthorized
|
||||
? Column(
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 24),
|
||||
child: NameCard(),
|
||||
),
|
||||
InkWell(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 18),
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.logout),
|
||||
title: Text("Sign out"),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
auth.signOff();
|
||||
setState(() {
|
||||
isAuthorized = false;
|
||||
});
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ActionCard(
|
||||
icon: const Icon(Icons.login, color: Colors.white),
|
||||
title: AppLocalizations.of(context)!.signIn,
|
||||
caption: AppLocalizations.of(context)!.signInCaption,
|
||||
onTap: () {
|
||||
auth.signIn(context).then((_) {
|
||||
authClient.isAuthorized().then((val) {
|
||||
setState(() => isAuthorized = val);
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
ActionCard(
|
||||
icon: const Icon(Icons.plus_one, color: Colors.white),
|
||||
title: AppLocalizations.of(context)!.signUp,
|
||||
caption: AppLocalizations.of(context)!.signUpCaption,
|
||||
onTap: () {
|
||||
launchUrl(getRequestUri('passport', '/auth/sign-up'));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NameCard extends StatelessWidget {
|
||||
const NameCard({super.key});
|
||||
|
||||
Future<Widget> renderAvatar() async {
|
||||
final profiles = await authClient.getProfiles();
|
||||
return CircleAvatar(backgroundImage: NetworkImage(profiles["picture"]));
|
||||
}
|
||||
|
||||
Future<Column> renderLabel() async {
|
||||
final profiles = await authClient.getProfiles();
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
profiles["nick"],
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text(profiles["email"])
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
child: InkWell(
|
||||
splashColor: Colors.indigo.withAlpha(30),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Row(
|
||||
children: [
|
||||
FutureBuilder(
|
||||
future: renderAvatar(),
|
||||
builder:
|
||||
(BuildContext context, AsyncSnapshot<Widget> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return snapshot.data!;
|
||||
} else {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
FutureBuilder(
|
||||
future: renderLabel(),
|
||||
builder:
|
||||
(BuildContext context, AsyncSnapshot<Column> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return snapshot.data!;
|
||||
} else {
|
||||
return const Column();
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ActionCard extends StatelessWidget {
|
||||
final Widget icon;
|
||||
final String title;
|
||||
final String caption;
|
||||
final Function onTap;
|
||||
|
||||
const ActionCard(
|
||||
{super.key,
|
||||
required this.onTap,
|
||||
required this.title,
|
||||
required this.caption,
|
||||
required this.icon});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
onTap: () => onTap(),
|
||||
child: Container(
|
||||
width: 320,
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: CircleAvatar(
|
||||
backgroundColor: Colors.indigo,
|
||||
child: icon,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
Text(caption),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
41
lib/screens/auth.dart
Executable file
41
lib/screens/auth.dart
Executable file
@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class AuthorizationScreen extends StatelessWidget {
|
||||
final Uri authorizationUrl;
|
||||
|
||||
const AuthorizationScreen(this.authorizationUrl, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.signIn),
|
||||
),
|
||||
body: Stack(children: [
|
||||
WebViewWidget(
|
||||
controller: WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(Colors.white)
|
||||
..setNavigationDelegate(NavigationDelegate(
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
if (request.url.startsWith('solian')) {
|
||||
Navigator.of(context).pop(request.url);
|
||||
WebViewCookieManager().clearCookies();
|
||||
return NavigationDecision.prevent;
|
||||
} else if (request.url.contains("sign-up")) {
|
||||
launchUrl(Uri.parse(request.url));
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
))
|
||||
..loadRequest(authorizationUrl)
|
||||
..clearCache(),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,15 +1,14 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:solian/models/pagination.dart';
|
||||
import 'package:solian/models/post.dart';
|
||||
import 'package:solian/utils/service_url.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:solian/providers/layout_provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:solian/widgets/posts/item.dart';
|
||||
import 'package:solian/widgets/wrapper.dart';
|
||||
|
||||
class ExploreScreen extends StatefulWidget {
|
||||
const ExploreScreen({super.key});
|
||||
@ -51,12 +50,6 @@ class _ExploreScreenState extends State<ExploreScreen> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
// Wait for the context
|
||||
context.read<LayoutConfig>().title =
|
||||
AppLocalizations.of(context)!.explore;
|
||||
});
|
||||
|
||||
super.initState();
|
||||
|
||||
_pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey));
|
||||
@ -64,18 +57,21 @@ class _ExploreScreenState extends State<ExploreScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => Future.sync(
|
||||
() => _pagingController.refresh(),
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 720),
|
||||
child: PagedListView<int, Post>.separated(
|
||||
pagingController: _pagingController,
|
||||
separatorBuilder: (context, index) => const Divider(thickness: 0.3),
|
||||
builderDelegate: PagedChildBuilderDelegate<Post>(
|
||||
itemBuilder: (context, item, index) => PostItem(item: item),
|
||||
return LayoutWrapper(
|
||||
title: AppLocalizations.of(context)!.explore,
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => Future.sync(
|
||||
() => _pagingController.refresh(),
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 720),
|
||||
child: PagedListView<int, Post>.separated(
|
||||
pagingController: _pagingController,
|
||||
separatorBuilder: (context, index) => const Divider(thickness: 0.3),
|
||||
builderDelegate: PagedChildBuilderDelegate<Post>(
|
||||
itemBuilder: (context, item, index) => PostItem(item: item),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user