mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Add references support
This commit is contained in:
		
							
								
								
									
										52
									
								
								lib/helpers/virtual_directory_helper.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								lib/helpers/virtual_directory_helper.dart
									
									
									
									
									
										Normal 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!");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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(),
 | 
			
		||||
                ),
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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!"));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user