mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 12:59:21 +00:00
Can create YouTube posts
This commit is contained in:
parent
bb62a3a159
commit
da48328c92
@ -167,6 +167,10 @@ class PostsHelper {
|
|||||||
request.addString("answers", post.survey.answers.join("<>"));
|
request.addString("answers", post.survey.answers.join("<>"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PostKind.YOUTUBE:
|
||||||
|
request.addString("youtube_id", post.youtubeId);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Unsupported post type :" + post.kind.toString());
|
throw Exception("Unsupported post type :" + post.kind.toString());
|
||||||
break;
|
break;
|
||||||
|
@ -31,6 +31,7 @@ class NewPost {
|
|||||||
final PostKind kind;
|
final PostKind kind;
|
||||||
final DateTime timeEnd;
|
final DateTime timeEnd;
|
||||||
final NewSurvey survey;
|
final NewSurvey survey;
|
||||||
|
final String youtubeId;
|
||||||
|
|
||||||
const NewPost({
|
const NewPost({
|
||||||
@required this.target,
|
@required this.target,
|
||||||
@ -43,6 +44,7 @@ class NewPost {
|
|||||||
@required this.pdf,
|
@required this.pdf,
|
||||||
@required this.timeEnd,
|
@required this.timeEnd,
|
||||||
@required this.survey,
|
@required this.survey,
|
||||||
|
@required this.youtubeId,
|
||||||
}) : assert(target != null),
|
}) : assert(target != null),
|
||||||
assert(targetID != null),
|
assert(targetID != null),
|
||||||
assert(visibility != null),
|
assert(visibility != null),
|
||||||
@ -52,5 +54,6 @@ class NewPost {
|
|||||||
assert(kind != PostKind.WEB_LINK || url != null),
|
assert(kind != PostKind.WEB_LINK || url != null),
|
||||||
assert(kind != PostKind.PDF || pdf != null),
|
assert(kind != PostKind.PDF || pdf != null),
|
||||||
assert(kind != PostKind.COUNTDOWN || timeEnd != null),
|
assert(kind != PostKind.COUNTDOWN || timeEnd != null),
|
||||||
assert(kind != PostKind.SURVEY || survey != null);
|
assert(kind != PostKind.SURVEY || survey != null),
|
||||||
|
assert(kind != PostKind.YOUTUBE || youtubeId != null);
|
||||||
}
|
}
|
||||||
|
28
lib/ui/dialogs/input_url_dialog.dart
Normal file
28
lib/ui/dialogs/input_url_dialog.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:comunic/ui/dialogs/single_input_dialog.dart';
|
||||||
|
import 'package:comunic/utils/input_utils.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Ask the user to enter an URL
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
/// Ask the user to enter an URL
|
||||||
|
Future<String> showInputURLDialog({
|
||||||
|
@required BuildContext context,
|
||||||
|
@required String title,
|
||||||
|
String initialURL,
|
||||||
|
}) async {
|
||||||
|
return await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (c) => SingleInputDialog(
|
||||||
|
title: title,
|
||||||
|
icon: Icons.link,
|
||||||
|
initialValue: initialURL,
|
||||||
|
label: "http://...",
|
||||||
|
checkInput: (s) => validateUrl(s),
|
||||||
|
errorMessage: tr("Invalid URL!"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
29
lib/ui/dialogs/input_youtube_link_dialog.dart
Normal file
29
lib/ui/dialogs/input_youtube_link_dialog.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:comunic/ui/dialogs/single_input_dialog.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Add YouTube link dialog
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
/// Ask the user to input a YouTube ID
|
||||||
|
Future<String> showInputYouTubeIDDialog(
|
||||||
|
BuildContext context, String initialID) async {
|
||||||
|
final value = await showDialog<String>(
|
||||||
|
context: context,
|
||||||
|
builder: (b) => SingleInputDialog(
|
||||||
|
title: tr("Input YouTube URL"),
|
||||||
|
icon: Icons.ondemand_video,
|
||||||
|
initialValue: initialID == null
|
||||||
|
? null
|
||||||
|
: "https://www.youtube.com/watch/?v=" + initialID,
|
||||||
|
label: tr("https://www.youtube.com/watch/?v="),
|
||||||
|
checkInput: (s) => RegExp(r'watch\/\?v=[\w\-\_]+').hasMatch(s),
|
||||||
|
errorMessage: tr("Invalid YouTube link!"),
|
||||||
|
));
|
||||||
|
|
||||||
|
if (value == null) return null;
|
||||||
|
|
||||||
|
return value.split("v=")[1].split("&")[0].split("#")[0];
|
||||||
|
}
|
@ -1,52 +1,45 @@
|
|||||||
import 'package:comunic/utils/input_utils.dart';
|
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
/// Ask the user to enter an URL
|
/// Ask the user to enter an URL
|
||||||
///
|
class SingleInputDialog extends StatefulWidget {
|
||||||
/// @author Pierre Hubert
|
|
||||||
|
|
||||||
/// Ask the user to enter an URL
|
|
||||||
Future<String> showInputURLDialog({
|
|
||||||
@required BuildContext context,
|
|
||||||
@required String title,
|
|
||||||
String initialURL,
|
|
||||||
}) async {
|
|
||||||
return await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (c) => _InputURLDialog(
|
|
||||||
title: title,
|
|
||||||
initialURL: initialURL,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _InputURLDialog extends StatefulWidget {
|
|
||||||
final String title;
|
final String title;
|
||||||
final String initialURL;
|
final IconData icon;
|
||||||
|
final String initialValue;
|
||||||
|
final String label;
|
||||||
|
final bool Function(String) checkInput;
|
||||||
|
final String errorMessage;
|
||||||
|
|
||||||
const _InputURLDialog({
|
const SingleInputDialog({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.title,
|
@required this.title,
|
||||||
@required this.initialURL,
|
@required this.icon,
|
||||||
|
@required this.initialValue,
|
||||||
|
@required this.label,
|
||||||
|
@required this.checkInput,
|
||||||
|
@required this.errorMessage,
|
||||||
}) : assert(title != null),
|
}) : assert(title != null),
|
||||||
|
assert(icon != null),
|
||||||
|
assert(label != null),
|
||||||
|
assert(checkInput != null),
|
||||||
|
assert(errorMessage != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
__InputURLDialogState createState() => __InputURLDialogState();
|
__InputURLDialogState createState() => __InputURLDialogState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class __InputURLDialogState extends State<_InputURLDialog> {
|
class __InputURLDialogState extends State<SingleInputDialog> {
|
||||||
TextEditingController _controller;
|
TextEditingController _controller;
|
||||||
|
|
||||||
bool get _isValid =>
|
bool get _isValid =>
|
||||||
_controller.text.isNotEmpty && validateUrl(_controller.text);
|
_controller.text.isNotEmpty && widget.checkInput(_controller.text);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_controller = new TextEditingController(text: widget.initialURL);
|
_controller = new TextEditingController(text: widget.initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -57,11 +50,11 @@ class __InputURLDialogState extends State<_InputURLDialog> {
|
|||||||
controller: _controller,
|
controller: _controller,
|
||||||
onChanged: (s) => setState(() {}),
|
onChanged: (s) => setState(() {}),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
icon: Icon(Icons.link),
|
icon: Icon(widget.icon),
|
||||||
alignLabelWithHint: true,
|
alignLabelWithHint: true,
|
||||||
labelText: "http://...",
|
labelText: widget.label,
|
||||||
errorText: _controller.text.isNotEmpty && !_isValid
|
errorText: _controller.text.isNotEmpty && !_isValid
|
||||||
? tr("Invalid URL!")
|
? widget.errorMessage
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
@ -5,8 +5,9 @@ import 'package:comunic/enums/post_target.dart';
|
|||||||
import 'package:comunic/enums/post_visibility_level.dart';
|
import 'package:comunic/enums/post_visibility_level.dart';
|
||||||
import 'package:comunic/helpers/posts_helper.dart';
|
import 'package:comunic/helpers/posts_helper.dart';
|
||||||
import 'package:comunic/models/new_post.dart';
|
import 'package:comunic/models/new_post.dart';
|
||||||
|
import 'package:comunic/ui/dialogs/input_url_dialog.dart';
|
||||||
|
import 'package:comunic/ui/dialogs/input_youtube_link_dialog.dart';
|
||||||
import 'package:comunic/ui/dialogs/new_survey_dialog.dart';
|
import 'package:comunic/ui/dialogs/new_survey_dialog.dart';
|
||||||
import 'package:comunic/ui/dialogs/url_dialog.dart';
|
|
||||||
import 'package:comunic/utils/files_utils.dart';
|
import 'package:comunic/utils/files_utils.dart';
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:comunic/utils/post_utils.dart';
|
import 'package:comunic/utils/post_utils.dart';
|
||||||
@ -54,6 +55,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
List<int> _postPDF;
|
List<int> _postPDF;
|
||||||
DateTime _timeEnd;
|
DateTime _timeEnd;
|
||||||
NewSurvey _postSurvey;
|
NewSurvey _postSurvey;
|
||||||
|
String _youtubeID;
|
||||||
|
|
||||||
bool get hasImage => _postImage != null;
|
bool get hasImage => _postImage != null;
|
||||||
|
|
||||||
@ -65,6 +67,8 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
|
|
||||||
bool get hasSurvey => _postSurvey != null;
|
bool get hasSurvey => _postSurvey != null;
|
||||||
|
|
||||||
|
bool get hasYoutTubeID => _youtubeID != null;
|
||||||
|
|
||||||
bool get canSubmitForm =>
|
bool get canSubmitForm =>
|
||||||
!_isCreating && _postTextController.text.length > 5 ||
|
!_isCreating && _postTextController.text.length > 5 ||
|
||||||
postKind != PostKind.TEXT;
|
postKind != PostKind.TEXT;
|
||||||
@ -80,6 +84,8 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
return PostKind.COUNTDOWN;
|
return PostKind.COUNTDOWN;
|
||||||
else if (hasSurvey)
|
else if (hasSurvey)
|
||||||
return PostKind.SURVEY;
|
return PostKind.SURVEY;
|
||||||
|
else if (hasYoutTubeID)
|
||||||
|
return PostKind.YOUTUBE;
|
||||||
else
|
else
|
||||||
return PostKind.TEXT;
|
return PostKind.TEXT;
|
||||||
}
|
}
|
||||||
@ -158,6 +164,13 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
selected: postKind == PostKind.SURVEY,
|
selected: postKind == PostKind.SURVEY,
|
||||||
onTap: _pickSurvey,
|
onTap: _pickSurvey,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Specify YouTube video ID
|
||||||
|
_PostOptionWidget(
|
||||||
|
icon: Icons.ondemand_video,
|
||||||
|
selected: postKind == PostKind.YOUTUBE,
|
||||||
|
onTap: _pickYouTubeVideo,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -222,6 +235,7 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
_postPDF = null;
|
_postPDF = null;
|
||||||
_timeEnd = null;
|
_timeEnd = null;
|
||||||
_postSurvey = null;
|
_postSurvey = null;
|
||||||
|
_youtubeID = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +336,20 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pick a new YouTube video
|
||||||
|
Future<void> _pickYouTubeVideo() async {
|
||||||
|
|
||||||
|
final youtubeID = await showInputYouTubeIDDialog(context, _youtubeID);
|
||||||
|
|
||||||
|
if (youtubeID == null) return;
|
||||||
|
|
||||||
|
_resetPostSelection();
|
||||||
|
setState(() {
|
||||||
|
_youtubeID = youtubeID;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// Submit new post
|
/// Submit new post
|
||||||
Future<void> _submitForm() async {
|
Future<void> _submitForm() async {
|
||||||
if (!canSubmitForm)
|
if (!canSubmitForm)
|
||||||
@ -331,16 +359,18 @@ class _PostCreateFormWidgetState extends State<PostCreateFormWidget> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await _postHelper.createPost(NewPost(
|
await _postHelper.createPost(NewPost(
|
||||||
target: widget.postTarget,
|
target: widget.postTarget,
|
||||||
targetID: widget.targetID,
|
targetID: widget.targetID,
|
||||||
visibility: _postVisibilityLevel,
|
visibility: _postVisibilityLevel,
|
||||||
content: _postTextController.text,
|
content: _postTextController.text,
|
||||||
kind: postKind,
|
kind: postKind,
|
||||||
image: _postImage,
|
image: _postImage,
|
||||||
url: _postURL,
|
url: _postURL,
|
||||||
pdf: _postPDF,
|
pdf: _postPDF,
|
||||||
timeEnd: _timeEnd,
|
timeEnd: _timeEnd,
|
||||||
survey: _postSurvey));
|
survey: _postSurvey,
|
||||||
|
youtubeId: _youtubeID,
|
||||||
|
));
|
||||||
setState(() => _isCreating = false);
|
setState(() => _isCreating = false);
|
||||||
|
|
||||||
showSimpleSnack(context, tr("The post has been successfully created!"));
|
showSimpleSnack(context, tr("The post has been successfully created!"));
|
||||||
|
Loading…
Reference in New Issue
Block a user