Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webview, the sliding effect in rich text editor is abnormal #1572

Closed
1 task done
Jinxishihenian opened this issue Dec 7, 2023 · 2 comments
Closed
1 task done

webview, the sliding effect in rich text editor is abnormal #1572

Jinxishihenian opened this issue Dec 7, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@Jinxishihenian
Copy link

Is there an existing issue for this?

Flutter Quill version

^8.5.5

Other Flutter Quill packages versions

No response

Steps to reproduce

  • The H5 page (three.js 3D effect) works fine when embedded in other Flutter pages via WebView, and touch and swipe events update the model's position smoothly.
  • In the FlutterQuill editor, when touching and swiping to change the position, the model only responds when I release the screen, at the moment of touch release.
  • Even for a normal H5 page within the flutter_quill editor, touch and swipe events do not work.

Expected results

  • How can I enable touch and swipe events to work on the embedded H5 page within the flutter_quill editor?

Actual results

Specifically, my H5 page contains a 3D model created with three.js, and I can touch and swipe to change the position and rotation of the model. But when I touch and swipe the embedded H5 view within the editor, the model does not immediately follow my touch trajectory. It only starts changing position when I lift my finger, as if it only detects the touch event when I release the focus.

Code sample

Code sample
class NotesEmbedBuilder extends EmbedBuilder {
  NotesEmbedBuilder({required this.addEditNote});

  Future<void> Function(BuildContext context, {Document? document}) addEditNote;

  @override
  String get key => 'notes';

  @override
  Widget build(
    BuildContext context,
    QuillController controller,
    Embed node,
    bool readOnly,
    bool inline,
    TextStyle textStyle,
  ) {
    // final notes = NotesBlockEmbed(node.value.data).document;

    return Material(
      color: Colors.transparent,
      child: Column(
        children: [
        /*  ListTile(
            title: Text(
              notes.toPlainText().replaceAll('\n', ' '),
              maxLines: 3,
              overflow: TextOverflow.ellipsis,
            ),
            leading: const Icon(Icons.notes),
            onTap: () => addEditNote(context, document: notes),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
              side: const BorderSide(color: Colors.grey),
            ),
          ),
          Text('测试'),*/
          Container(
            width: 360,
            height: 360,
            child:WebviewUtil(),
          ),
        ],
      ),
    );
  }
}
class WebviewUtil extends StatefulWidget {
  const WebviewUtil({super.key});

  @override
  State<WebviewUtil> createState() => _WebviewWidgetState();
}

class _WebviewWidgetState extends State<WebviewUtil> {
  late WebViewController controller;
  late String url;
  late String titleName;
  bool hasSearch = false;
  var container = Container(
    margin: const EdgeInsets.only(right: 6),
    padding: const EdgeInsets.all(8),
    child: InkWell(
      onTap: () {
        // Get.toNamed(Routers.search);
      },
      // child: SvgPicture.asset(
      //   'assets/images/home/icon_search.svg',
      //   width: 24,
      // ),
    ),
  );

  @override
  Widget build(BuildContext context) {
    // titleName = Get.arguments['title'];
    return Scaffold(
 /*     appBar: buildAppBar(
          titleName: titleName, actions: [if (hasSearch) container]),*/
      body: WebViewWidget(controller: controller),
    );
  }

  @override
  void initState() {
    super.initState();

    // url = 'http://127.0.0.1:8000/h5/#/external/model/21443?minimal=1&note=1&lock=true&record_id=oqS-q8AmTvItLbXd8u4z7';
    url = 'https://www.evdo.vip/h5/#/external/model/21151?minimal=1&note=1&lock=true&record_id=HpzBsnSG_4MAIZ1rfAnJk';
/*    hasSearch = Get.arguments['hasSearch'].runtimeType != Null
        ? Get.arguments['hasSearch']
        : false;*/
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..addJavaScriptChannel('handleMessage', onMessageReceived: (parma) {
        // Get.back(result: {"refresh": true});
      })
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // Update loading bar.
          },
          onPageStarted: (String url) {},
          onPageFinished: (String url) {},
          onWebResourceError: (WebResourceError error) {},
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://pan.baidu.com')) {
              // print('blocking navigation to $request}');
              _launchURL(request.url);
              return NavigationDecision.prevent;
            }

            // print('allowing navigation to $request');
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse(url));
  }

  _launchURL(String url) async {
    if (await launchUrl(Uri.parse(url))) {
      debugPrint('Could not launch $url');
    }
  }
}

class MyQuillEditor extends StatelessWidget {
  const MyQuillEditor({
    required this.configurations,
    required this.scrollController,
    required this.focusNode,
    required this.addEditNote,
    super.key,
  });

  final QuillEditorConfigurations configurations;
  final ScrollController scrollController;
  final FocusNode focusNode;
  final addEditNote;

  @override
  Widget build(BuildContext context) {
    return QuillEditor(
      scrollController: scrollController,
      focusNode: focusNode,
      configurations: configurations.copyWith(
        customStyles: const DefaultStyles(
          h1: DefaultTextBlockStyle(
            TextStyle(
              fontSize: 32,
              height: 1.15,
              fontWeight: FontWeight.w300,
            ),
            VerticalSpacing(16, 0),
            VerticalSpacing(0, 0),
            null,
          ),
          sizeSmall: TextStyle(fontSize: 9),
          subscript: TextStyle(
            fontFamily: 'SF-UI-Display',
            fontFeatures: [FontFeature.subscripts()],
          ),
          superscript: TextStyle(
            fontFamily: 'SF-UI-Display',
            fontFeatures: [FontFeature.superscripts()],
          ),
        ),
        scrollable: true,
        placeholder: 'Start writting your notes...',
        padding: const EdgeInsets.all(16),
        onImagePaste: (imageBytes) async {
          if (isWeb()) {
            return null;
          }
          // We will save it to system temporary files
          final newFileName = '${DateTime.now().toIso8601String()}.png';
          final newPath = path.join(
            io.Directory.systemTemp.path,
            newFileName,
          );
          final file = await io.File(
            newPath,
          ).writeAsBytes(imageBytes, flush: true);
          return file.path;
        },
        embedBuilders: [
          ...(isWeb()
              ? FlutterQuillEmbeds.editorWebBuilders()
              : FlutterQuillEmbeds.editorBuilders(
                  imageEmbedConfigurations: QuillEditorImageEmbedConfigurations(
                    imageErrorWidgetBuilder: (context, error, stackTrace) {
                      return Text(
                        'Error while loading an image: ${error.toString()}',
                      );
                    },
                    imageProviderBuilder: (imageUrl) {
                      // cached_network_image is supported
                      // only for Android, iOS and web

                      // We will use it only if image from network
                      if (isAndroid(supportWeb: false) ||
                          isIOS(supportWeb: false) ||
                          isWeb()) {
                        if (isHttpBasedUrl(imageUrl)) {
                          return CachedNetworkImageProvider(
                            imageUrl,
                          );
                        }
                      }
                      return getImageProviderByImageSource(
                        imageUrl,
                        imageProviderBuilder: null,
                        assetsPrefix: QuillSharedExtensionsConfigurations.get(
                                context: context)
                            .assetsPrefix,
                      );
                    },
                  ),
                )),
          TimeStampEmbedBuilderWidget(),
          NotesEmbedBuilder(
            addEditNote: addEditNote,
          ),
        ],
        builder: (context, rawEditor) {
          // The `desktop_drop` plugin doesn't support iOS platform for now
          if (isIOS(supportWeb: false)) {
            return rawEditor;
          }
          return rawEditor;
          return GestureDetector(
         /*   onDragDone: (details) {
              final scaffoldMessenger = ScaffoldMessenger.of(context);
              final file = details.files.first;
              final isSupported = imageFileExtensions.any(file.name.endsWith);
              if (!isSupported) {
                scaffoldMessenger.showText(
                  'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions',
                );
                return;
              }
              context.requireQuillController.insertImageBlock(
                imageSource: file.path,
              );
              scaffoldMessenger.showText('Image is inserted.');
            },*/
            child: rawEditor,
          );
        },
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration > #

[Upload media here]

9cff62edff15b31e009a20b499db233d.mp4

Logs

Logs
[Paste your logs here]
@Jinxishihenian Jinxishihenian added the bug Something isn't working label Dec 7, 2023
@Jinxishihenian
Copy link
Author

Scroll conflict problem. When I disable rich text scrolling, the content inside the WebView can slide normally

@Jinxishihenian
Copy link
Author

This issue has nothing to do with rich text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant