Compare commits
No commits in common. "bad485ac1d4f1da9f3d5d37456e2eae2a279705d" and "7647542421324a79310f0aa823a66396e0df87ed" have entirely different histories.
bad485ac1d
...
7647542421
@ -29,8 +29,6 @@ def get(user, id):
|
|||||||
owner = user and (user.get('_id') == proj['user'])
|
owner = user and (user.get('_id') == proj['user'])
|
||||||
if not owner and proj['visibility'] != 'public':
|
if not owner and proj['visibility'] != 'public':
|
||||||
raise util.errors.BadRequest('Forbidden')
|
raise util.errors.BadRequest('Forbidden')
|
||||||
if obj['type'] == 'file' and 'storedName' in obj:
|
|
||||||
obj['url'] = uploads.get_presigned_url('projects/{0}/{1}'.format(proj['_id'], obj['storedName']))
|
|
||||||
if obj['type'] == 'pattern' and 'preview' in obj and '.png' in obj['preview']:
|
if obj['type'] == 'pattern' and 'preview' in obj and '.png' in obj['preview']:
|
||||||
obj['previewUrl'] = uploads.get_presigned_url('projects/{0}/{1}'.format(proj['_id'], obj['preview']))
|
obj['previewUrl'] = uploads.get_presigned_url('projects/{0}/{1}'.format(proj['_id'], obj['preview']))
|
||||||
del obj['preview']
|
del obj['preview']
|
||||||
|
1
mobile/flutter_jank_metrics_01.json
Normal file
1
mobile/flutter_jank_metrics_01.json
Normal file
File diff suppressed because one or more lines are too long
1
mobile/flutter_jank_metrics_02.json
Normal file
1
mobile/flutter_jank_metrics_02.json
Normal file
File diff suppressed because one or more lines are too long
@ -6,41 +6,31 @@ import 'group_noticeboard.dart';
|
|||||||
import 'group_members.dart';
|
import 'group_members.dart';
|
||||||
|
|
||||||
class _GroupScreenState extends State<GroupScreen> {
|
class _GroupScreenState extends State<GroupScreen> {
|
||||||
final String id;
|
|
||||||
Map<String, dynamic>? _group;
|
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
|
List<Widget> _widgetOptions = <Widget> [];
|
||||||
|
final Map<String, dynamic> _group;
|
||||||
|
|
||||||
_GroupScreenState(this.id) { }
|
_GroupScreenState(this._group) {
|
||||||
|
_widgetOptions = <Widget> [
|
||||||
@override
|
GroupNoticeBoardTab(this._group),
|
||||||
void initState() {
|
GroupMembersTab(this._group)
|
||||||
fetchGroup();
|
];
|
||||||
super.initState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchGroup() async {
|
void _onItemTapped(int index) {
|
||||||
Api api = Api();
|
setState(() {
|
||||||
var data = await api.request('GET', '/groups/' + id);
|
_selectedIndex = index;
|
||||||
if (data['success'] == true) {
|
});
|
||||||
setState(() {
|
|
||||||
_group = data['payload'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_group?['name'] ?? 'Group')
|
title: Text(_group['name'])
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: _group != null ?
|
child: _widgetOptions.elementAt(_selectedIndex),
|
||||||
[
|
|
||||||
GroupNoticeBoardTab(_group!),
|
|
||||||
GroupMembersTab(_group!)
|
|
||||||
].elementAt(_selectedIndex)
|
|
||||||
: CircularProgressIndicator(),
|
|
||||||
),
|
),
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
items: const <BottomNavigationBarItem>[
|
items: const <BottomNavigationBarItem>[
|
||||||
@ -55,17 +45,15 @@ class _GroupScreenState extends State<GroupScreen> {
|
|||||||
],
|
],
|
||||||
currentIndex: _selectedIndex,
|
currentIndex: _selectedIndex,
|
||||||
selectedItemColor: Colors.pink[600],
|
selectedItemColor: Colors.pink[600],
|
||||||
onTap: (int index) => setState(() {
|
onTap: _onItemTapped,
|
||||||
_selectedIndex = index;
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupScreen extends StatefulWidget {
|
class GroupScreen extends StatefulWidget {
|
||||||
final String id;
|
final Map<String,dynamic> group;
|
||||||
GroupScreen(this.id) { }
|
GroupScreen(this.group) { }
|
||||||
@override
|
@override
|
||||||
_GroupScreenState createState() => _GroupScreenState(id);
|
_GroupScreenState createState() => _GroupScreenState(group);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'group.dart';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
import 'model.dart';
|
import 'model.dart';
|
||||||
import 'lib.dart';
|
import 'lib.dart';
|
||||||
@ -16,8 +16,6 @@ class _GroupsTabState extends State<GroupsTab> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getGroups() async {
|
void getGroups() async {
|
||||||
AppModel model = Provider.of<AppModel>(context, listen: false);
|
|
||||||
if (model.user == null) return;
|
|
||||||
setState(() => _loading = true);
|
setState(() => _loading = true);
|
||||||
Api api = Api();
|
Api api = Api();
|
||||||
var data = await api.request('GET', '/groups');
|
var data = await api.request('GET', '/groups');
|
||||||
@ -38,7 +36,14 @@ class _GroupsTabState extends State<GroupsTab> {
|
|||||||
}
|
}
|
||||||
return Card(
|
return Card(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () => context.push('/groups/' + group['_id']),
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => GroupScreen(group),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: Icon(Icons.people),
|
leading: Icon(Icons.people),
|
||||||
trailing: Icon(Icons.keyboard_arrow_right),
|
trailing: Icon(Icons.keyboard_arrow_right),
|
||||||
|
@ -263,7 +263,12 @@ class PatternCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.push('/' + object['userObject']['username'] + '/' + object['projectObject']['path'] + '/' + object['_id']);
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ObjectScreen(object, object['projectObject']),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
@ -13,9 +13,7 @@ import 'register.dart';
|
|||||||
import 'onboarding.dart';
|
import 'onboarding.dart';
|
||||||
import 'home.dart';
|
import 'home.dart';
|
||||||
import 'project.dart';
|
import 'project.dart';
|
||||||
import 'object.dart';
|
|
||||||
import 'settings.dart';
|
import 'settings.dart';
|
||||||
import 'group.dart';
|
|
||||||
|
|
||||||
final router = GoRouter(
|
final router = GoRouter(
|
||||||
routes: [
|
routes: [
|
||||||
@ -39,9 +37,7 @@ final router = GoRouter(
|
|||||||
GoRoute(path: '/onboarding', builder: (context, state) => OnboardingScreen()),
|
GoRoute(path: '/onboarding', builder: (context, state) => OnboardingScreen()),
|
||||||
GoRoute(path: '/home', builder: (context, state) => HomeScreen()),
|
GoRoute(path: '/home', builder: (context, state) => HomeScreen()),
|
||||||
GoRoute(path: '/settings', builder: (context, state) => SettingsScreen()),
|
GoRoute(path: '/settings', builder: (context, state) => SettingsScreen()),
|
||||||
GoRoute(path: '/groups/:id', builder: (context, state) => GroupScreen(state.pathParameters['id']!)),
|
GoRoute(path: '/:username/:id', builder: (context, state) => ProjectScreen(state.pathParameters['username']!, state.pathParameters['id']!)),
|
||||||
GoRoute(path: '/:username/:path', builder: (context, state) => ProjectScreen(state.pathParameters['username']!, state.pathParameters['path']!)),
|
|
||||||
GoRoute(path: '/:username/:path/:id', builder: (context, state) => ObjectScreen(state.pathParameters['username']!, state.pathParameters['path']!, state.pathParameters['id']!)),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -118,7 +114,9 @@ class Startup extends StatelessWidget {
|
|||||||
_handled = true;
|
_handled = true;
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
String? token = prefs.getString('apiToken');
|
String? token = prefs.getString('apiToken');
|
||||||
|
print('Nooo');
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
|
print('HEE');
|
||||||
AppModel model = Provider.of<AppModel>(context, listen: false);
|
AppModel model = Provider.of<AppModel>(context, listen: false);
|
||||||
await model.setToken(token!);
|
await model.setToken(token!);
|
||||||
FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
|
FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
|
||||||
|
@ -3,7 +3,6 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:flutter_html/flutter_html.dart';
|
import 'package:flutter_html/flutter_html.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
import 'util.dart';
|
import 'util.dart';
|
||||||
@ -11,32 +10,30 @@ import 'patterns/pattern.dart';
|
|||||||
import 'patterns/viewer.dart';
|
import 'patterns/viewer.dart';
|
||||||
|
|
||||||
class _ObjectScreenState extends State<ObjectScreen> {
|
class _ObjectScreenState extends State<ObjectScreen> {
|
||||||
final String username;
|
final Map<String,dynamic> _project;
|
||||||
final String projectPath;
|
Map<String,dynamic> _object;
|
||||||
final String id;
|
Map<String,dynamic>? _pattern;
|
||||||
final Map<String,dynamic>? project;
|
|
||||||
Map<String,dynamic>? object;
|
|
||||||
Map<String,dynamic>? pattern;
|
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
final Function? onUpdate;
|
final Function? onUpdate;
|
||||||
final Function? onDelete;
|
final Function? onDelete;
|
||||||
final Api api = Api();
|
final Api api = Api();
|
||||||
final Util util = Util();
|
final Util util = Util();
|
||||||
|
|
||||||
_ObjectScreenState(this.username, this.projectPath, this.id, {this.object, this.project, this.onUpdate, this.onDelete}) { }
|
_ObjectScreenState(this._object, this._project, {this.onUpdate, this.onDelete}) { }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
fetchObject();
|
if (_object['type'] == 'pattern') {
|
||||||
|
_fetchPattern();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchObject() async {
|
void _fetchPattern() async {
|
||||||
var data = await api.request('GET', '/objects/' + id);
|
var data = await api.request('GET', '/objects/' + _object['_id']);
|
||||||
if (data['success'] == true) {
|
if (data['success'] == true) {
|
||||||
setState(() {
|
setState(() {
|
||||||
object = data['payload'];
|
_pattern = data['payload']['pattern'];
|
||||||
pattern = data['payload']['pattern'];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,14 +41,14 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
void _shareObject() async {
|
void _shareObject() async {
|
||||||
setState(() => _isLoading = true);
|
setState(() => _isLoading = true);
|
||||||
File? file;
|
File? file;
|
||||||
if (object!['type'] == 'pattern') {
|
if (_object['type'] == 'pattern') {
|
||||||
var data = await api.request('GET', '/objects/' + id + '/wif');
|
var data = await api.request('GET', '/objects/' + _object['_id'] + '/wif');
|
||||||
if (data['success'] == true) {
|
if (data['success'] == true) {
|
||||||
file = await util.writeFile(object!['name'] + '.wif', data['payload']['wif']);
|
file = await util.writeFile(_object['name'] + '.wif', data['payload']['wif']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String fileName = Uri.file(object!['url']).pathSegments.last;
|
String fileName = Uri.file(_object['url']).pathSegments.last;
|
||||||
file = await api.downloadFile(object!['url'], fileName);
|
file = await api.downloadFile(_object['url'], fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@ -61,10 +58,12 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _deleteObject(BuildContext context, BuildContext modalContext) async {
|
void _deleteObject(BuildContext context, BuildContext modalContext) async {
|
||||||
var data = await api.request('DELETE', '/objects/' + id);
|
var data = await api.request('DELETE', '/objects/' + _object['_id']);
|
||||||
if (data['success']) {
|
if (data['success']) {
|
||||||
context.go('/home');
|
Navigator.pop(context);
|
||||||
onDelete!(id);
|
Navigator.pop(modalContext);
|
||||||
|
Navigator.pop(context);
|
||||||
|
onDelete!(_object['_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
CupertinoDialogAction(
|
CupertinoDialogAction(
|
||||||
isDefaultAction: true,
|
isDefaultAction: true,
|
||||||
child: Text('No'),
|
child: Text('No'),
|
||||||
onPressed: () => context.pop(),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
CupertinoDialogAction(
|
CupertinoDialogAction(
|
||||||
isDestructiveAction: true,
|
isDestructiveAction: true,
|
||||||
@ -106,22 +105,22 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
TextButton(
|
TextButton(
|
||||||
child: Text('CANCEL'),
|
child: Text('CANCEL'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.pop();
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('OK'),
|
child: Text('OK'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var data = await api.request('PUT', '/objects/' + id, {'name': renameController.text});
|
var data = await api.request('PUT', '/objects/' + _object['_id'], {'name': renameController.text});
|
||||||
if (data['success']) {
|
if (data['success']) {
|
||||||
context.pop();
|
Navigator.pop(context);
|
||||||
object!['name'] = data['payload']['name'];
|
_object['name'] = data['payload']['name'];
|
||||||
onUpdate!(id, data['payload']);
|
onUpdate!(_object['_id'], data['payload']);
|
||||||
setState(() {
|
setState(() {
|
||||||
object = object;
|
_object = _object;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
context.pop();
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -137,7 +136,7 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
return CupertinoActionSheet(
|
return CupertinoActionSheet(
|
||||||
title: Text('Manage this object'),
|
title: Text('Manage this object'),
|
||||||
cancelButton: CupertinoActionSheetAction(
|
cancelButton: CupertinoActionSheetAction(
|
||||||
onPressed: () => modalContext.pop(),
|
onPressed: () => Navigator.of(modalContext).pop(),
|
||||||
child: Text('Cancel')
|
child: Text('Cancel')
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
@ -157,22 +156,15 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget getObjectWidget() {
|
Widget getObjectWidget() {
|
||||||
if (object == null) {
|
if (_object['isImage'] == true) {
|
||||||
return Center(child: Column(
|
return Image.network(_object['url']);
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [CircularProgressIndicator()]
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
else if (object!['isImage'] == true && object!['url'] != null) {
|
else if (_object['type'] == 'pattern') {
|
||||||
print(object!['url']);
|
if (_pattern != null) {
|
||||||
return Image.network(object!['url']);
|
return PatternViewer(_pattern!, withEditor: true);
|
||||||
}
|
|
||||||
else if (object!['type'] == 'pattern') {
|
|
||||||
if (pattern != null) {
|
|
||||||
return PatternViewer(pattern!, withEditor: true);
|
|
||||||
}
|
}
|
||||||
else if (object!['previewUrl'] != null) {
|
else if (_object['previewUrl'] != null) {
|
||||||
return Image.network(object!['previewUrl']!);;
|
return Image.network(_object['previewUrl']!);;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Column(
|
return Column(
|
||||||
@ -192,7 +184,7 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
Text('Treadl cannot display this type of item.'),
|
Text('Treadl cannot display this type of item.'),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
ElevatedButton(child: Text('View file'), onPressed: () {
|
ElevatedButton(child: Text('View file'), onPressed: () {
|
||||||
launch(object!['url']);
|
launch(_object['url']);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
@ -202,11 +194,11 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String description = '';
|
String description = '';
|
||||||
if (object?['description'] != null)
|
if (_object['description'] != null)
|
||||||
description = object!['description']!;
|
description = _object['description'];
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(object?['name'] ?? 'Object'),
|
title: Text(_object['name']),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.ios_share),
|
icon: Icon(Icons.ios_share),
|
||||||
@ -236,15 +228,12 @@ class _ObjectScreenState extends State<ObjectScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ObjectScreen extends StatefulWidget {
|
class ObjectScreen extends StatefulWidget {
|
||||||
final String username;
|
final Map<String,dynamic> _object;
|
||||||
final String projectPath;
|
final Map<String,dynamic> _project;
|
||||||
final String id;
|
|
||||||
final Map<String,dynamic>? object;
|
|
||||||
final Map<String,dynamic>? project;
|
|
||||||
final Function? onUpdate;
|
final Function? onUpdate;
|
||||||
final Function? onDelete;
|
final Function? onDelete;
|
||||||
ObjectScreen(this.username, this.projectPath, this.id, {this.object, this.project, this.onUpdate, this.onDelete}) { }
|
ObjectScreen(this._object, this._project, {this.onUpdate, this.onDelete}) { }
|
||||||
@override
|
@override
|
||||||
_ObjectScreenState createState() => _ObjectScreenState(username, projectPath, id, object: object, project: project, onUpdate: onUpdate, onDelete: onDelete);
|
_ObjectScreenState createState() => _ObjectScreenState(_object, _project, onUpdate: onUpdate, onDelete: onDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
|
|||||||
CupertinoButton(
|
CupertinoButton(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: Text('Get started', style: TextStyle(color: Colors.pink)),
|
child: Text('Get started', style: TextStyle(color: Colors.pink)),
|
||||||
onPressed: () => context.go('/home'),
|
onPressed: () => context.go('/'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
import 'util.dart';
|
import 'util.dart';
|
||||||
import 'model.dart';
|
import 'object.dart';
|
||||||
|
|
||||||
class _ProjectScreenState extends State<ProjectScreen> {
|
class _ProjectScreenState extends State<ProjectScreen> {
|
||||||
final String username;
|
final String username;
|
||||||
@ -252,7 +252,12 @@ class _ProjectScreenState extends State<ProjectScreen> {
|
|||||||
return new Card(
|
return new Card(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.push('/' + username + '/' + projectPath + '/' + object['_id']);
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ObjectScreen(object, project!, onUpdate: _onUpdateObject, onDelete: _onDeleteObject),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: leader,
|
leading: leader,
|
||||||
@ -264,31 +269,8 @@ class _ProjectScreenState extends State<ProjectScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getBody() {
|
|
||||||
if (_loading || project == null)
|
|
||||||
return CircularProgressIndicator();
|
|
||||||
else if ((_objects != null && _objects.length > 0) || _creating)
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: _objects.length + (_creating ? 1 : 0),
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return getObjectCard(index);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
else
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text('This project is currently empty', style: TextStyle(fontSize: 20), textAlign: TextAlign.center),
|
|
||||||
Image(image: AssetImage('assets/empty.png'), width: 300),
|
|
||||||
Text('Add a pattern file, an image, or something else to this project using the + button below.', textAlign: TextAlign.center),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
AppModel model = Provider.of<AppModel>(context);
|
|
||||||
User? user = model.user;
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(project?['name'] ?? 'Project'),
|
title: Text(project?['name'] ?? 'Project'),
|
||||||
@ -307,13 +289,33 @@ class _ProjectScreenState extends State<ProjectScreen> {
|
|||||||
) : SizedBox(width: 0),
|
) : SizedBox(width: 0),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
body: Container(
|
body: _loading ?
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.all(10.0),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: CircularProgressIndicator()
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
margin: const EdgeInsets.all(10.0),
|
margin: const EdgeInsets.all(10.0),
|
||||||
alignment: Alignment.center,
|
child: ((_objects != null && _objects.length > 0) || _creating) ?
|
||||||
child: getBody(),
|
ListView.builder(
|
||||||
|
itemCount: _objects.length + (_creating ? 1 : 0),
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return getObjectCard(index);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text('This project is currently empty', style: TextStyle(fontSize: 20), textAlign: TextAlign.center),
|
||||||
|
Image(image: AssetImage('assets/empty.png'), width: 300),
|
||||||
|
Text('Add a pattern file, an image, or something else to this project using the + button below.', textAlign: TextAlign.center),
|
||||||
|
])
|
||||||
),
|
),
|
||||||
floatingActionButtonLocation: ExpandableFab.location,
|
floatingActionButtonLocation: ExpandableFab.location,
|
||||||
floatingActionButton: user != null ? ExpandableFab(
|
floatingActionButton: ExpandableFab(
|
||||||
distance: 70,
|
distance: 70,
|
||||||
type: ExpandableFabType.up,
|
type: ExpandableFabType.up,
|
||||||
openButtonBuilder: RotateFloatingActionButtonBuilder(
|
openButtonBuilder: RotateFloatingActionButtonBuilder(
|
||||||
@ -353,7 +355,7 @@ class _ProjectScreenState extends State<ProjectScreen> {
|
|||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
) : null,
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@ class _ProjectsTabState extends State<ProjectsTab> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getProjects() async {
|
void getProjects() async {
|
||||||
AppModel model = Provider.of<AppModel>(context, listen: false);
|
|
||||||
if (model.user == null) return;
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_loading = true;
|
_loading = true;
|
||||||
});
|
});
|
||||||
@ -133,8 +131,6 @@ class _ProjectsTabState extends State<ProjectsTab> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
AppModel model = Provider.of<AppModel>(context);
|
|
||||||
User? user = model.user;
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('My Projects'),
|
title: Text('My Projects'),
|
||||||
@ -152,11 +148,11 @@ class _ProjectsTabState extends State<ProjectsTab> {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: getBody()
|
child: getBody()
|
||||||
),
|
),
|
||||||
floatingActionButton: user != null ? FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: showNewProjectDialog,
|
onPressed: showNewProjectDialog,
|
||||||
child: _creatingProject ? CircularProgressIndicator(backgroundColor: Colors.white) : Icon(Icons.add),
|
child: _creatingProject ? CircularProgressIndicator(backgroundColor: Colors.white) : Icon(Icons.add),
|
||||||
backgroundColor: Colors.pink[500],
|
backgroundColor: Colors.pink[500],
|
||||||
) : null,
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,6 @@ class SettingsScreen extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
AppModel model = Provider.of<AppModel>(context);
|
|
||||||
User? user = model.user;
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('About Treadl'),
|
title: Text('About Treadl'),
|
||||||
@ -98,24 +96,16 @@ class SettingsScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
|
|
||||||
user != null ? Column(
|
ListTile(
|
||||||
children: [
|
leading: Icon(Icons.exit_to_app),
|
||||||
ListTile(
|
title: Text('Logout'),
|
||||||
leading: Icon(Icons.exit_to_app),
|
onTap: () => _logout(context),
|
||||||
title: Text('Logout'),
|
),
|
||||||
onTap: () => _logout(context),
|
ListTile(
|
||||||
),
|
leading: Icon(Icons.delete),
|
||||||
ListTile(
|
title: Text('Delete Account'),
|
||||||
leading: Icon(Icons.delete),
|
onTap: () => _deleteAccount(context),
|
||||||
title: Text('Delete Account'),
|
|
||||||
onTap: () => _deleteAccount(context),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
) : CupertinoButton(
|
|
||||||
color: Colors.pink,
|
|
||||||
child: Text('Join Treadl', style: TextStyle(color: Colors.white)),
|
|
||||||
onPressed: () => context.push('/welcome'),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
|
Loading…
Reference in New Issue
Block a user