1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-10-22 22:43:22 +00:00

Add references support

This commit is contained in:
Pierre HUBERT 2020-04-16 12:06:01 +02:00
parent 7de882338d
commit 2bb75da017
6 changed files with 127 additions and 8 deletions

View File

@ -0,0 +1,52 @@
import 'package:comunic/models/api_request.dart';
import 'package:flutter/material.dart';
/// Virtual directory helper
///
/// @author Pierre Hubert
enum VirtualDirectoryType { USER, GROUP, NONE }
class VirtualDirectoryResult {
final VirtualDirectoryType type;
final int id;
const VirtualDirectoryResult({
@required this.type,
this.id,
}) : assert(type != null);
}
class VirtualDirectoryHelper {
/// Find a virtual directory
Future<VirtualDirectoryResult> find(String directory) async {
final response = await APIRequest(
uri: "virtualDirectory/find",
needLogin: true,
args: {"directory": directory}).exec();
switch (response.code) {
case 404:
return VirtualDirectoryResult(type: VirtualDirectoryType.NONE);
case 200:
final id = response.getObject()["id"];
final kind = response.getObject()["kind"];
switch (kind) {
case "user":
return VirtualDirectoryResult(
type: VirtualDirectoryType.USER, id: id);
case "group":
return VirtualDirectoryResult(
type: VirtualDirectoryType.GROUP, id: id);
default:
throw Exception("Unsupported virtual directory kind: $kind");
}
break;
default:
throw new Exception("Could not get virtual directory!");
}
}
}

View File

@ -22,10 +22,6 @@ import 'login_route.dart';
class HomeRoute extends StatefulWidget {
@override
State<StatefulWidget> createState() => _HomeRouteState();
/// Get current instance of Home controller
static HomeController of(BuildContext context) =>
context.findAncestorStateOfType<HomeController>();
}
class CurrPage {
@ -45,6 +41,11 @@ class CurrPage {
/// Public interface of home controller
abstract class HomeController extends State<HomeRoute> {
/// Get current instance of Home controller
static HomeController of(BuildContext context) =>
context.findAncestorStateOfType<HomeController>();
/// Open a specific group page specified by its [groupID]
void openGroup(int groupID);
}

View File

@ -67,7 +67,7 @@ class _GroupsListScreenState extends SafeState<GroupsListScreen> {
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _deleteGroup(g)),
onTap: () => HomeRoute.of(context).openGroup(g.id),
onTap: () => HomeController.of(context).openGroup(g.id),
))
.toList(),
),

View File

@ -1,5 +1,6 @@
import 'package:comunic/utils/bbcode_parser.dart';
import 'package:comunic/utils/input_utils.dart';
import 'package:comunic/utils/navigation_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_emoji/flutter_emoji.dart';
import 'package:url_launcher/url_launcher.dart';
@ -32,17 +33,17 @@ class TextWidget extends StatelessWidget {
if (this.parseBBcode)
return BBCodeParsedWidget(
text: content,
parseCallback: (style, text) => _parseLinks(text, style),
parseCallback: (style, text) => _parseLinks(context, text, style),
);
// Just parse link
return RichText(
text: TextSpan(children: _parseLinks(content, style)),
text: TextSpan(children: _parseLinks(context, content, style)),
);
}
/// Sub parse function
List<InlineSpan> _parseLinks(String text, TextStyle style) {
List<InlineSpan> _parseLinks(BuildContext context, String text, TextStyle style) {
var buff = StringBuffer();
final list = new List<InlineSpan>();
@ -78,6 +79,25 @@ class TextWidget extends StatelessWidget {
buff.write(" ");
}
// Check if it is a user reference
else if(validateUserReference(word)) {
changeWordType();
list.add(
WidgetSpan(
child: InkWell(
child: Text(
word,
style: style.copyWith(color: Colors.blueAccent),
),
onTap: () => openVirtualDirectory(context, word),
),
),
);
buff.write(" ");
}
// Simple word
else {
buff.write(word);

View File

@ -27,3 +27,7 @@ bool validateUrl(String url) {
return false;
}
}
/// Validate user reference
bool validateUserReference(String ref) =>
RegExp(r'@[a-zA-Z0-9]+').hasMatch(ref);

View File

@ -1,5 +1,9 @@
import 'package:comunic/helpers/virtual_directory_helper.dart';
import 'package:comunic/ui/routes/home_route.dart';
import 'package:comunic/ui/routes/single_post_route.dart';
import 'package:comunic/ui/routes/user_page_route.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
@ -26,3 +30,41 @@ void openPostFullScreen(int postID, BuildContext context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (c) => SinglePostRoute(postID: postID)));
}
/// Open a virtual directory
void openVirtualDirectory(BuildContext context, String directory) async {
if (directory.startsWith("@")) directory = directory.substring(1);
try {
final result = await VirtualDirectoryHelper().find(directory);
switch (result.type) {
case VirtualDirectoryType.USER:
openUserPage(context: context, userID: result.id);
break;
case VirtualDirectoryType.GROUP:
HomeController.of(context).openGroup(result.id);
break;
case VirtualDirectoryType.NONE:
await showDialog(
context: context,
builder: (c) => AlertDialog(
title: Text(tr("Error")),
content: Text(tr("Could not find related resource!")),
actions: <Widget>[
MaterialButton(
child: Text(tr("OK")),
onPressed: () => Navigator.of(c).pop(),
)
],
));
break;
}
} catch (e, stack) {
print(e);
print(stack);
showSimpleSnack(context, tr("Could not search virtual directory!"));
}
}