feat: added 'Add Video' feature

This commit is contained in:
jideguru 2021-06-06 21:09:09 +01:00
parent 066b2019f2
commit 7b809401ec
6 changed files with 100 additions and 25 deletions

View File

@ -474,6 +474,25 @@ var editor = {
}
},
insertVideo: function(url, width, height, fromDevice) {
console.log(url);
if (fromDevice) {
this._insertVideo(url, width, height);
} else {
this._insertYoutubeVideo(url, width, height);
}
},
_insertYoutubeVideo: function(url, width, height) {
var html = '<iframe width="'+ width +'" height="'+ height +'" src="' + url + '" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>';
this._insertHtml(html);
},
_insertVideo: function(url, width, height) {
var html = '<video width="'+ width +'" height="'+ height +'" controls><source type="video/mp4" src="'+ url +'"></video>'
this._insertHtml(html);
},
insertCheckbox: function(text) {
var editor = this;

View File

@ -88,6 +88,11 @@ class BasicDemo extends StatelessWidget {
String base64String = 'data:image/png;base64, $base64';
return base64String;
},
getVideoUrl: (video) {
String link = 'https://file-examples-com.github.io/uploads/2017/'
'04/file_example_MP4_480_1_5MG.mp4';
return link;
},
),
);
}

View File

@ -88,11 +88,7 @@ class RichEditorState extends State<RichEditor> {
children: [
Visibility(
visible: widget.editorOptions!.barPosition == BarPosition.TOP,
child: EditorToolBar(
getImageUrl: widget.getImageUrl,
javascriptExecutor: javascriptExecutor,
enableVideo: widget.editorOptions!.enableVideo,
),
child: _buildToolBar(),
),
Expanded(
child: InAppWebView(
@ -135,16 +131,21 @@ class RichEditorState extends State<RichEditor> {
),
Visibility(
visible: widget.editorOptions!.barPosition == BarPosition.BOTTOM,
child: EditorToolBar(
getImageUrl: widget.getImageUrl,
javascriptExecutor: javascriptExecutor,
enableVideo: widget.editorOptions!.enableVideo,
),
child: _buildToolBar(),
),
],
);
}
_buildToolBar() {
return EditorToolBar(
getImageUrl: widget.getImageUrl,
getVideoUrl: widget.getVideoUrl,
javascriptExecutor: javascriptExecutor,
enableVideo: widget.editorOptions!.enableVideo,
);
}
_setInitialValues() async {
if (widget.value != null) await javascriptExecutor.setHtml(widget.value!);
if (widget.editorOptions!.padding != null)

View File

@ -198,6 +198,23 @@ class JavascriptExecutorBase {
);
}
insertVideo(String url,
{int? width, int? height, bool fromDevice = true}) async {
bool? local;
local = fromDevice ? true : null;
if (width == null) width = 300;
if (height == null) height = 220;
// check if link is yt link
if (url.contains('youtu')) {
// Get Video id from link.
String youtubeId = url.split(r'?v=')[1];
url = 'https://www.youtube.com/embed/$youtubeId';
}
await executeJavascript(
"insertVideo('$url', '$width', '$height', $local);",
);
}
insertCheckbox(String text) async {
await executeJavascript("insertCheckbox('$text');");
}

View File

@ -71,7 +71,6 @@ class EditorToolBar extends StatelessWidget {
onTap: () async {
var link = await showDialog(
context: context,
barrierDismissible: false,
builder: (_) {
return InsertImageDialog();
},
@ -88,11 +87,27 @@ class EditorToolBar extends StatelessWidget {
},
),
Visibility(
visible: false,
visible: enableVideo!,
child: TabButton(
tooltip: 'Insert video',
icon: Icons.video_call_sharp,
onTap: () async {},
onTap: () async {
var link = await showDialog(
context: context,
builder: (_) {
return InsertImageDialog(isVideo: true);
},
);
if(link != null) {
if (getVideoUrl != null && link[2]) {
link[0] = await getVideoUrl!(File(link[0]));
}
await javascriptExecutor.insertVideo(
link[0],
fromDevice: link[2],
);
}
},
),
),
TabButton(

View File

@ -4,6 +4,10 @@ import 'package:image_picker/image_picker.dart';
import 'custom_dialog_template.dart';
class InsertImageDialog extends StatefulWidget {
final bool isVideo;
InsertImageDialog({this.isVideo = false});
@override
_InsertImageDialogState createState() => _InsertImageDialogState();
}
@ -21,7 +25,7 @@ class _InsertImageDialogState extends State<InsertImageDialog> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Image link'),
Text(widget.isVideo ? 'Video link' : 'Image link'),
ElevatedButton(
onPressed: () => getImage(),
child: Text('...'),
@ -34,12 +38,21 @@ class _InsertImageDialogState extends State<InsertImageDialog> {
hintText: '',
),
),
SizedBox(height: 20.0),
Text('Alt text (optional)'),
TextField(
controller: alt,
decoration: InputDecoration(
hintText: '',
Visibility(
visible: !widget.isVideo,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20.0),
Text('Alt text (optional)'),
TextField(
controller: alt,
decoration: InputDecoration(
hintText: '',
),
),
],
),
),
],
@ -50,11 +63,16 @@ class _InsertImageDialogState extends State<InsertImageDialog> {
Future getImage() async {
final picker = ImagePicker();
var image = await picker.getImage(
source: ImageSource.gallery,
maxWidth: 800.0,
maxHeight: 600.0,
);
var image;
if (widget.isVideo) {
image = await picker.getVideo(source: ImageSource.gallery);
} else {
image = await picker.getImage(
source: ImageSource.gallery,
maxWidth: 800.0,
maxHeight: 600.0,
);
}
if (image != null) {
link.text = image.path;