This commit is contained in:
parent
6d21d6a4e6
commit
d28e5f1197
6 changed files with 367 additions and 31 deletions
|
@ -12,8 +12,9 @@ steps:
|
||||||
- git config --global --add safe.directory /home/mobiledevops/.flutter-sdk
|
- git config --global --add safe.directory /home/mobiledevops/.flutter-sdk
|
||||||
- echo "Getting Dependencies"
|
- echo "Getting Dependencies"
|
||||||
- flutter pub get
|
- flutter pub get
|
||||||
|
- flutter pub upgrade
|
||||||
- echo "Building..."
|
- echo "Building..."
|
||||||
- flutter build apk
|
- flutter build apk --debug
|
||||||
- echo "Build Completed!"
|
- echo "Build Completed!"
|
||||||
- name: windows build
|
- name: windows build
|
||||||
image: debian
|
image: debian
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:ui';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:OpenContacts/auxiliary.dart';
|
import 'package:OpenContacts/auxiliary.dart';
|
||||||
import 'package:OpenContacts/clients/session_client.dart';
|
import 'package:OpenContacts/clients/session_client.dart';
|
||||||
|
@ -5,9 +6,15 @@ import 'package:OpenContacts/models/session.dart';
|
||||||
import 'package:OpenContacts/widgets/default_error_widget.dart';
|
import 'package:OpenContacts/widgets/default_error_widget.dart';
|
||||||
import 'package:OpenContacts/widgets/formatted_text.dart';
|
import 'package:OpenContacts/widgets/formatted_text.dart';
|
||||||
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
import 'package:html/dom.dart' hide Text;
|
||||||
|
import 'package:indexed/indexed.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:gradient_borders/gradient_borders.dart';
|
||||||
|
|
||||||
class SessionList extends StatefulWidget {
|
class SessionList extends StatefulWidget {
|
||||||
const SessionList({super.key});
|
const SessionList({super.key});
|
||||||
|
@ -74,50 +81,175 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
|
||||||
),
|
),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final session = data[index];
|
final session = data[index];
|
||||||
return Card(
|
return Container( //Make this a container, shit doesn't like it when it's a class already
|
||||||
elevation: 0,
|
decoration: const BoxDecoration(
|
||||||
shape: RoundedRectangleBorder(
|
gradient: LinearGradient(
|
||||||
side: BorderSide(
|
begin: Alignment.centerLeft,
|
||||||
color: Theme.of(context).colorScheme.outline,
|
end: Alignment.centerRight,
|
||||||
),
|
colors: <Color>[
|
||||||
borderRadius: BorderRadius.circular(30),
|
Color.fromARGB(255, 248, 248, 112),
|
||||||
|
Color.fromARGB(255, 230, 158, 80),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
|
border: GradientBoxBorder(
|
||||||
|
width: 2,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.centerLeft,
|
||||||
|
end: Alignment.centerRight,
|
||||||
|
colors: <Color>[
|
||||||
|
Color.fromARGB(255, 248, 248, 112),
|
||||||
|
Color.fromARGB(255, 230, 158, 80),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.all( // I wouldn't have known that this was the right way to write
|
||||||
|
Radius.circular(10)
|
||||||
|
),
|
||||||
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push(MaterialPageRoute(builder: (context) => SessionView(session: session)));
|
.push(MaterialPageRoute(builder: (context) => SessionView(session: session)));
|
||||||
},
|
},
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
child: Column(
|
child: Indexer(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Indexed(
|
||||||
flex: 5,
|
index: 1,
|
||||||
child: ClipRRect(
|
child: Positioned(
|
||||||
borderRadius: BorderRadius.circular(30),
|
top: 0,
|
||||||
child: Hero(
|
bottom: 80,
|
||||||
tag: session.id,
|
left: 0,
|
||||||
child: CachedNetworkImage(
|
right: 0,
|
||||||
imageUrl: Aux.resdbToHttp(session.thumbnailUrl),
|
child: ClipRRect(
|
||||||
fit: BoxFit.cover,
|
borderRadius: const BorderRadius.only(
|
||||||
errorWidget: (context, url, error) => const Center(
|
topLeft: Radius.circular(10),
|
||||||
child: Icon(
|
topRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
child: Hero(
|
||||||
|
tag: session.id,
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: Aux.resdbToHttp(session.thumbnailUrl),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorWidget:(context, url, error) => const Center(
|
||||||
|
child: Icon(
|
||||||
Icons.broken_image,
|
Icons.broken_image,
|
||||||
size: 64,
|
size: 64,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
placeholder: (context, uri) =>
|
placeholder: (context, url) =>
|
||||||
const Center(child: CircularProgressIndicator()),
|
const Center(child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Indexed(
|
||||||
flex: 1
|
index: 2,
|
||||||
child: Padding(padding: ,),
|
child: Positioned(
|
||||||
|
top: 160,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Container(
|
||||||
|
width: 200,
|
||||||
|
height: 50,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
Expanded(
|
Indexed(
|
||||||
|
index: 3,
|
||||||
|
child: Positioned(
|
||||||
|
top: 140,
|
||||||
|
bottom: 75,
|
||||||
|
left: 0,
|
||||||
|
right: 100,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Indexed(
|
||||||
|
index: 4,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 130,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child:Icon(
|
||||||
|
Icons.group
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Icon(
|
||||||
|
Icons.dns
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
), //Due to some limitations, Icons and Texts are on different layers
|
||||||
|
Indexed(
|
||||||
|
index: 5,
|
||||||
|
child: Column(
|
||||||
|
//mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 143,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
" ${(session.sessionUsers.length - (session.headlessHost? 1 : 0)).toString().padLeft(2, "0")}/${session.maxUsers.toString().padLeft(2, "0")}",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: FormattedText(
|
||||||
|
//textAlign: Align(1,1),
|
||||||
|
session.formattedName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
" ${session.hostUsername}",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
/*child: Column(
|
||||||
|
Expanded( //2
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 16),
|
||||||
|
@ -178,7 +310,7 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),*/
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,7 +31,7 @@ class _SessionListAppBarState extends State<SessionListAppBar> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.filter_alt_outlined),
|
icon: const Icon(Icons.filter_list),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -7,4 +7,189 @@ import 'package:OpenContacts/widgets/formatted_text.dart';
|
||||||
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class NextSessionList extends StatefulWidget {
|
||||||
|
const NextSessionList({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NextSessionList> createState() => _SessionListState();
|
||||||
|
}
|
||||||
|
class onKeyIntent extends Intent{
|
||||||
|
const onKeyIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKey = SingleActivator(LogicalKeyboardKey.f5);
|
||||||
|
|
||||||
|
class _SessionListState extends State<NextSessionList> with AutomaticKeepAliveClientMixin {
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
final sClient = Provider.of<SessionClient>(context, listen: false);
|
||||||
|
if (sClient.sessionsFuture == null) {
|
||||||
|
sClient.initSessions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
super.build(context);
|
||||||
|
return ChangeNotifierProvider.value(
|
||||||
|
value: Provider.of<SessionClient>(context),
|
||||||
|
child: Consumer<SessionClient>(
|
||||||
|
builder: (BuildContext context, SessionClient sClient, Widget? child) {
|
||||||
|
return FutureBuilder<List<Session>>(
|
||||||
|
future: sClient.sessionsFuture,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final data = snapshot.data ?? [];
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
sClient.reloadSessions();
|
||||||
|
try {
|
||||||
|
await sClient.sessionsFuture;
|
||||||
|
} catch (e) {
|
||||||
|
if (context.mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: data.isEmpty && snapshot.connectionState == ConnectionState.done
|
||||||
|
? const DefaultErrorWidget(
|
||||||
|
title: "No Sessions Found",
|
||||||
|
message: "Try to adjust your filters",
|
||||||
|
iconOverride: Icons.question_mark,
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: GridView.builder(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
itemCount: data.length,
|
||||||
|
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
|
maxCrossAxisExtent: 256,
|
||||||
|
crossAxisSpacing: 4,
|
||||||
|
mainAxisSpacing: 1,
|
||||||
|
childAspectRatio: .8,
|
||||||
|
),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final session = data[index];
|
||||||
|
return Card(
|
||||||
|
elevation: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
side: BorderSide(
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(builder: (context) => SessionView(session: session)));
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
child: Hero(
|
||||||
|
tag: session.id,
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: Aux.resdbToHttp(session.thumbnailUrl),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorWidget: (context, url, error) => const Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.broken_image,
|
||||||
|
size: 64,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
placeholder: (context, uri) =>
|
||||||
|
const Center(child: CircularProgressIndicator()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 16),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: FormattedText(
|
||||||
|
session.formattedName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"Host: ${session.hostUsername}",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Color.fromARGB(234, 151, 107, 61)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"${(session.sessionUsers.length - (session.headlessHost? 1 : 0)).toString().padLeft(2, "0")}/${session.maxUsers.toString().padLeft(2, "0")} Online",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface
|
||||||
|
.withOpacity(.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) const LinearProgressIndicator()
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get wantKeepAlive => true;
|
||||||
|
}
|
||||||
|
|
16
pubspec.lock
16
pubspec.lock
|
@ -408,6 +408,14 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
gradient_borders:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: gradient_borders
|
||||||
|
sha256: b1cd969552c83f458ff755aa68e13a0327d09f06c3f42f471b423b01427f21f8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
hive:
|
hive:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -520,6 +528,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.1+1"
|
version: "0.2.1+1"
|
||||||
|
indexed:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: indexed
|
||||||
|
sha256: "3509a2a7ad1dbd7280da377661129e0b0a2f5e8d6d75f10400f07397f95324df"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.8"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -65,6 +65,8 @@ dependencies:
|
||||||
share_plus: ^7.1.0
|
share_plus: ^7.1.0
|
||||||
ffmpeg_kit_flutter_audio: ^6.0.3
|
ffmpeg_kit_flutter_audio: ^6.0.3
|
||||||
background_downloader: ^7.12.2
|
background_downloader: ^7.12.2
|
||||||
|
indexed: ^0.0.8
|
||||||
|
gradient_borders: ^1.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in a new issue