public void UpdateContent(AppTask data) { taskData = data; TaskDescription.Text = data.Description; info = JsonConvert.DeserializeObject <AdditionalInfoData>(data.JsonData); if (!string.IsNullOrWhiteSpace(info.ImageUrl)) { string imgUrl = Common.ServerUtils.GetUploadUrl(info.ImageUrl); ImageService.Instance.LoadUrl(imgUrl).Into(InfoImage); NSLayoutConstraint.DeactivateConstraints(new NSLayoutConstraint[] { hideImageConstraint }); NSLayoutConstraint.ActivateConstraints(new NSLayoutConstraint[] { showImageConstraint }); } else { NSLayoutConstraint.DeactivateConstraints(new NSLayoutConstraint[] { showImageConstraint }); NSLayoutConstraint.ActivateConstraints(new NSLayoutConstraint[] { hideImageConstraint }); } if (!string.IsNullOrWhiteSpace(info.ExternalUrl)) { InfoButton.Alpha = 1; InfoButton.TouchUpInside += (a, e) => { UIApplication.SharedApplication.OpenUrl(new NSUrl(info.ExternalUrl)); }; } else { InfoButton.Alpha = 0; } }
private static string GetNewTaskJsonData(LearningTask task, List <FileUpload> files) { if (task.TaskType.IdName == "MATCH_PHOTO" || task.TaskType.IdName == "LISTEN_AUDIO" || (task.TaskType.IdName == "DRAW_PHOTO" && !task.JsonData.StartsWith("TASK::", StringComparison.InvariantCulture))) { FileUpload taskF = files.FirstOrDefault(fi => fi.LocalFilePath == task.JsonData); if (taskF != null && !string.IsNullOrWhiteSpace(taskF.RemoteFilePath)) { return(taskF.RemoteFilePath); } return(null); } // Info is trickier, as the JsonData is an actual object, with the URL stored inside if (task.TaskType.IdName == "INFO") { AdditionalInfoData data = JsonConvert.DeserializeObject <AdditionalInfoData>(task.JsonData); FileUpload taskF = files.FirstOrDefault(fi => fi.LocalFilePath == data.ImageUrl); if (taskF != null) { data.ImageUrl = taskF.RemoteFilePath; } return(JsonConvert.SerializeObject(data)); } return(null); }
protected override void FinishButton_TouchUpInside(object sender, EventArgs e) { if (UpdateBasicTask()) { if (string.IsNullOrWhiteSpace(currentImagePath)) { currentImagePath = previousImage; } else if (!string.IsNullOrWhiteSpace(previousImage) && !previousImage.StartsWith("upload")) { // new image replaces old one, delete the previous image File.Delete(AppUtils.GetPathForLocalFile(previousImage)); } string imgUrl = (string.IsNullOrWhiteSpace(currentImagePath)) ? "" : currentImagePath.StartsWith("upload") ? currentImagePath : Path.Combine(Directory.GetParent(currentImagePath).Name, Path.GetFileName(currentImagePath)); AdditionalInfoData data = new AdditionalInfoData { ImageUrl = imgUrl, ExternalUrl = chosenLink }; thisTask.JsonData = JsonConvert.SerializeObject(data); UpdateActivity(); Unwind(); } }
private void ContinueToNext(AdditionalInfoData data) { if (newTask == null) { newTask = new LearningTask(); } newTask.Description = infoField.Text; newTask.TaskType = taskType; newTask.JsonData = JsonConvert.SerializeObject(data); string json = JsonConvert.SerializeObject(newTask, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize, MaxDepth = 5 }); Intent myIntent = (editing) ? new Intent(this, typeof(CreateActivityOverviewActivity)) : new Intent(this, typeof(CreateChooseTaskTypeActivity)); myIntent.PutExtra("JSON", json); SetResult(global::Android.App.Result.Ok, myIntent); Finish(); }
private static string GetPathIfFile(LearningTask t) { string thisFile = null; switch (t.TaskType.IdName) { case "MATCH_PHOTO": case "LISTEN_AUDIO": thisFile = t.JsonData; break; case "DRAW_PHOTO": if (!t.JsonData.StartsWith("TASK::", StringComparison.InvariantCulture)) { thisFile = t.JsonData; } break; case "INFO": AdditionalInfoData data = JsonConvert.DeserializeObject <AdditionalInfoData>(t.JsonData); if (!string.IsNullOrWhiteSpace(data.ImageUrl)) { thisFile = data.ImageUrl; } break; } return(thisFile == null || thisFile.StartsWith("upload") ? null : thisFile); }
private void Prepare() { // Check if this is editing an existing task: if so, populate fields string editJson = Intent.GetStringExtra("EDIT") ?? ""; newTask = JsonConvert.DeserializeObject <LearningTask>(editJson); if (newTask != null) { addTaskBtn.SetText(Resource.String.saveChanges); AdditionalInfoData addData = JsonConvert.DeserializeObject <AdditionalInfoData>(newTask.JsonData); infoField.Text = newTask.Description; urlField.Text = addData.ExternalUrl; taskType = newTask.TaskType; editing = true; if (!string.IsNullOrWhiteSpace(addData.ImageUrl)) { if (addData.ImageUrl.StartsWith("upload")) { string imageUrl = ServerUtils.GetUploadUrl(addData.ImageUrl); ImageService.Instance.LoadUrl(imageUrl) .Transform(new CircleTransformation()) .Into(imageView); } else { editCachePath = Path.Combine( Common.LocalData.Storage.GetCacheFolder(null), "editcache-" + DateTime.UtcNow.ToString("MM-dd-yyyy-HH-mm-ss-fff")); File.Copy(addData.ImageUrl, editCachePath, true); Java.IO.File cachedFile = new Java.IO.File(editCachePath); selectedImage = global::Android.Net.Uri.FromFile(cachedFile); ImageService.Instance.LoadFile(selectedImage.Path).Transform(new CircleTransformation()).Into(imageView); } originalPath = addData.ImageUrl; } } else { // If edit is null, get the tasktype from JSON string jsonData = Intent.GetStringExtra("JSON") ?? ""; taskType = JsonConvert.DeserializeObject <TaskType>(jsonData, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); newTask = new LearningTask { TaskType = taskType }; } if (selectedImage == null && originalPath == null) { AndroidUtils.LoadTaskTypeIcon(taskType, imageView); } }
private void AddTaskBtn_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(infoField.Text)) { new global::Android.Support.V7.App.AlertDialog.Builder(this) .SetTitle(Resource.String.ErrorTitle) .SetMessage(Resource.String.createNewActivityTaskInstruct) .SetPositiveButton(Resource.String.dialog_ok, (a, b) => { }) .Show(); return; } AdditionalInfoData data = new AdditionalInfoData(); if (!string.IsNullOrWhiteSpace(urlField.Text)) { Uri uriResult; bool validUrl = Uri.TryCreate(urlField.Text, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); if (!validUrl) { new global::Android.Support.V7.App.AlertDialog.Builder(this) .SetTitle(Resource.String.ErrorTitle) .SetMessage(Resource.String.createNewInfoUrlInvalid) .SetPositiveButton(Resource.String.dialog_ok, (a, b) => { }) .Show(); return; } data.ExternalUrl = uriResult.AbsoluteUri; } if (selectedImage == null && originalPath == null) { new global::Android.Support.V7.App.AlertDialog.Builder(this) .SetTitle(Resource.String.WarningTitle) .SetMessage(Resource.String.createNewInfoNoImage) .SetCancelable(false) .SetNegativeButton(Resource.String.dialog_cancel, (a, b) => { return; }) .SetPositiveButton(Resource.String.Continue, (a, b) => { ContinueToNext(data); }) .Show(); return; } if (selectedImage != null && (!editing || selectedImage.Path != editCachePath)) { data.ImageUrl = selectedImage.Path; } else { data.ImageUrl = originalPath; } ContinueToNext(data); }
public override void ViewDidLoad() { base.ViewDidLoad(); AddImageButton.TouchUpInside += AddImageButton_TouchUpInside; if (!string.IsNullOrWhiteSpace(thisTask?.JsonData)) { AdditionalInfoData data = JsonConvert.DeserializeObject <AdditionalInfoData>(thisTask.JsonData); previousImage = data.ImageUrl; if (!string.IsNullOrWhiteSpace(previousImage)) { if (previousImage.StartsWith("upload")) { ImageService.Instance.LoadUrl(ServerUtils.GetUploadUrl(previousImage)) .Into(AccompanyingImage); } else { ImageService.Instance.LoadFile( AppUtils.GetPathForLocalFile(previousImage)) .Into(AccompanyingImage); } } if (!string.IsNullOrWhiteSpace(data.ExternalUrl)) { chosenLink = data.ExternalUrl; LinkLabel.Text = data.ExternalUrl; } } folderPath = Common.LocalData.Storage.GetCacheFolder("created"); UpdateLabels(); AddLinkButton.TouchUpInside += AddLinkButton_TouchUpInside; }
private static TaskFileInfo GetInfoForTask(LearningTask task) { string tt = task.TaskType?.IdName; if (tt == "MATCH_PHOTO" || tt == "LISTEN_AUDIO" || (tt == "DRAW_PHOTO" && !task.JsonData.StartsWith("TASK::", StringComparison.OrdinalIgnoreCase))) { return(new TaskFileInfo { extension = ServerUtils.GetFileExtension(task.TaskType.IdName), fileUrl = task.JsonData }); } else if (tt == "INFO") { AdditionalInfoData infoData = JsonConvert.DeserializeObject <AdditionalInfoData>(task.JsonData); if (!string.IsNullOrWhiteSpace(infoData.ImageUrl)) { return(new TaskFileInfo { extension = ServerUtils.GetFileExtension(task.TaskType.IdName), fileUrl = infoData.ImageUrl }); } } return(null); }
private void OnItemClick(object sender, int position) { // If Finish button clicked if (position == adapter.ItemCount - 1) { PackageForUpload(); return; } string json = JsonConvert.SerializeObject(adapter.Items[position], new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Serialize, MaxDepth = 5 }); string taskType = adapter.Items[position].TaskType.IdName; switch (taskType) { case "TAKE_VIDEO": case "TAKE_PHOTO": case "MATCH_PHOTO": { lastReqIntent = new Intent(this, typeof(CameraActivity)); lastReqIntent.PutExtra("JSON", json); lastReqIntent.PutExtra("ACTID", learningActivity.Id); List <string> perms = new List <string> { global::Android.Manifest.Permission.Camera, global::Android.Manifest.Permission.AccessFineLocation }; List <string> titles = new List <string> { base.Resources.GetString(Resource.String.permissionCameraTitle), base.Resources.GetString(Resource.String.permissionLocationTitle) }; List <string> explanations = new List <string> { base.Resources.GetString(Resource.String.permissionPhotoExplanation), base.Resources.GetString(Resource.String.permissionLocationExplanation) }; // Video tasks also require the microphone if (taskType == "TAKE_VIDEO") { perms.Add(global::Android.Manifest.Permission.RecordAudio); titles.Add(base.Resources.GetString(Resource.String.permissionMicTitle)); explanations.Add(base.Resources.GetString(Resource.String.permissionMicExplanation)); } AndroidUtils.CallWithPermission(perms.ToArray(), titles.ToArray(), explanations.ToArray(), lastReqIntent, adapter.Items[position].Id, PermReqId, this); break; } case "DRAW": case "DRAW_PHOTO": { Intent drawActivity = new Intent(this, typeof(DrawingActivity)); drawActivity.PutExtra("JSON", json); if (taskType == "DRAW_PHOTO" && adapter.Items[position].JsonData.StartsWith("TASK::", StringComparison.OrdinalIgnoreCase)) { int id = -1; int.TryParse(adapter.Items[position].JsonData.Substring(6), out id); string[] paths = JsonConvert.DeserializeObject <string[]>(adapter.GetTaskWithId(id).CompletionData.JsonData); drawActivity.PutExtra("PREVIOUS_PHOTO", paths[0]); drawActivity.PutExtra("ACTIVITY_ID", learningActivity.Id); } StartActivityForResult(drawActivity, adapter.Items[position].Id); break; } case "MAP_MARK": lastReqIntent = new Intent(this, typeof(LocationMarkerActivity)); lastReqIntent.PutExtra("JSON", json); AndroidUtils.CallWithPermission(new string[] { global::Android.Manifest.Permission.AccessFineLocation }, new string[] { base.Resources.GetString(Resource.String.permissionLocationTitle) }, new string[] { base.Resources.GetString(Resource.String.permissionLocationExplanation) }, lastReqIntent, adapter.Items[position].Id, PermReqId, this); break; case "LOC_HUNT": lastReqIntent = new Intent(this, typeof(LocationHuntActivity)); lastReqIntent.PutExtra("JSON", json); AndroidUtils.CallWithPermission(new string[] { global::Android.Manifest.Permission.AccessFineLocation }, new string[] { base.Resources.GetString(Resource.String.permissionLocationTitle) }, new string[] { base.Resources.GetString(Resource.String.permissionLocationExplanation) }, lastReqIntent, adapter.Items[position].Id, PermReqId, this); break; case "SCAN_QR": lastReqIntent = new Intent(this, typeof(ScanningActivity)); lastReqIntent.PutExtra("JSON", json); StartActivityForResult(lastReqIntent, adapter.Items[position].Id); break; case "REC_AUDIO": lastReqIntent = new Intent(this, typeof(RecordAudioActivity)); lastReqIntent.PutExtra("JSON", json); AndroidUtils.CallWithPermission(new string[] { global::Android.Manifest.Permission.RecordAudio }, new string[] { base.Resources.GetString(Resource.String.permissionMicTitle) }, new string[] { base.Resources.GetString(Resource.String.permissionMicExplanation) }, lastReqIntent, adapter.Items[position].Id, PermReqId, this); break; case "LISTEN_AUDIO": ShowMedia(position, -1); break; case "INFO": AdditionalInfoData data = JsonConvert.DeserializeObject <AdditionalInfoData>(adapter.Items[position].JsonData); global::Android.Net.Uri uri = global::Android.Net.Uri.Parse(data.ExternalUrl); Intent intent = new Intent(Intent.ActionView, uri); StartActivity(intent); break; default: Toast.MakeText(this, "Unknown task type! :(", ToastLength.Short).Show(); break; } }
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { TaskViewHolder vh; Type thisType = holder.GetType(); OnBind = true; if (Curator) { if (position == 0) { return; } } if (position == 0 || (Curator && position == 1)) { // Activity description + entered names (if required) vh = holder as TaskViewHolderName; if (vh == null) { return; } vh.Title.Text = description; vh.Description.Text = context.Resources.GetString(Resource.String.TasksTitle); ((TaskViewHolderName)vh).NameSection.Visibility = (reqName) ? ViewStates.Visible : ViewStates.Gone; ((TaskViewHolderName)vh).EnteredNames.Text = names; return; } if (position == Items.Count - 1) { // Finish button if (holder is ButtonViewHolder bvh) { bvh.Button.Enabled = true; } return; } string taskType = Items[position].TaskType.IdName; if (thisType == typeof(TaskViewHolderInfo)) { AdditionalInfoData taskInfo = JsonConvert.DeserializeObject <AdditionalInfoData>(Items[position].JsonData); vh = holder as TaskViewHolderInfo; Items[position].IsCompleted = true; if (!string.IsNullOrWhiteSpace(taskInfo.ImageUrl)) { Items[position].ImageUrl = taskInfo.ImageUrl; } TaskViewHolderInfo taskViewHolderInfo = (TaskViewHolderInfo)vh; if (taskViewHolderInfo != null) { taskViewHolderInfo.Button.Visibility = (string.IsNullOrWhiteSpace(taskInfo.ExternalUrl)) ? ViewStates.Gone : ViewStates.Visible; } } else if (thisType == typeof(TaskViewHolderRecordAudio)) { vh = holder as TaskViewHolderRecordAudio; if (vh != null) { ((TaskViewHolderRecordAudio)vh).StartTaskButton.Text = context.Resources.GetString(Resource.String.StartBtn); if (!string.IsNullOrWhiteSpace(Items[position].CompletionData.JsonData)) { List <string> audioPaths = JsonConvert.DeserializeObject <List <string> >(Items[position].CompletionData.JsonData); ((TaskViewHolderRecordAudio)vh).ShowResults(audioPaths, context); Items[position].IsCompleted = true; } else { Items[position].IsCompleted = false; ((TaskViewHolderRecordAudio)vh).ClearResults(); } } } else if (thisType == typeof(TaskViewHolderRecordVideo)) { vh = holder as TaskViewHolderRecordVideo; if (vh != null) { ((TaskViewHolderRecordVideo)vh).StartTaskButton.Text = context.Resources.GetString(Resource.String.RecBtn); if (!string.IsNullOrWhiteSpace(Items[position].CompletionData.JsonData)) { List <string> videoPaths = JsonConvert.DeserializeObject <List <string> >(Items[position].CompletionData.JsonData); ((TaskViewHolderRecordVideo)vh).ShowResults(videoPaths, context); Items[position].IsCompleted = true; } else { Items[position].IsCompleted = false; ((TaskViewHolderRecordVideo)vh).ClearResults(); } } } else if (thisType == typeof(TaskViewHolderResultList)) { vh = holder as TaskViewHolderResultList; bool btnEnabled = true; string btnText; if (taskType == "DRAW" || taskType == "DRAW_PHOTO") { btnText = context.Resources.GetString(Resource.String.StartDrawBtn); if (taskType == "DRAW_PHOTO") { btnEnabled = !int.TryParse(Items[position].JsonData, out var idResult) || GetTaskWithId(idResult).IsCompleted; if (!btnEnabled) { btnText = context.Resources.GetString(Resource.String.TaskBtnNotReady); } } } else { btnText = context.Resources.GetString(Resource.String.TakePhotoBtn); } if (vh != null) { ((TaskViewHolderResultList)vh).StartTaskButton.Text = btnText; ((TaskViewHolderResultList)vh).StartTaskButton.Enabled = btnEnabled; if (!string.IsNullOrWhiteSpace(Items[position].CompletionData.JsonData)) { List <string> photoPaths = JsonConvert.DeserializeObject <List <string> >(Items[position].CompletionData.JsonData); ((TaskViewHolderResultList)vh).ShowResults(photoPaths, context); Items[position].IsCompleted = true; } else { Items[position].IsCompleted = false; ((TaskViewHolderResultList)vh).ClearResults(); } } } else if (thisType == typeof(TaskViewHolderBtn)) { vh = holder as TaskViewHolderBtn; string btnText = context.Resources.GetString(Resource.String.TaskBtn); if (taskType == "LISTEN_AUDIO") { btnText = context.Resources.GetString(Resource.String.ListenBtn); } TaskViewHolderBtn viewHolderBtn = (TaskViewHolderBtn)vh; if (viewHolderBtn != null) { viewHolderBtn.Button.Text = btnText; } } else if (thisType == typeof(TaskViewHolderTextEntry)) { vh = holder as TaskViewHolderTextEntry; if (vh != null) { ((TaskViewHolderTextEntry)vh).TextField.Text = Items[position].CompletionData.JsonData; Items[position].IsCompleted = !string.IsNullOrWhiteSpace(((TaskViewHolderTextEntry)vh).TextField.Text); } } else { if (thisType == typeof(TaskViewHolderMultipleChoice)) { vh = holder as TaskViewHolderMultipleChoice; RadioGroup radios = ((TaskViewHolderMultipleChoice)vh)?.RadioGroup; string[] choices = JsonConvert.DeserializeObject <string[]>(Items[position].JsonData); int.TryParse(Items[position].CompletionData.JsonData, out var answeredInd); if (radios != null && radios.ChildCount == 0) { int index = 0; foreach (string option in choices) { RadioButton rad = new RadioButton(context) { Text = option }; rad.SetPadding(0, 0, 0, 5); rad.TextSize = 16; radios.AddView(rad); if (Items[position].IsCompleted && answeredInd == index) { ((RadioButton)radios.GetChildAt(answeredInd)).Checked = true; } index++; } } if (answeredInd == -1) { Items[position].IsCompleted = false; } if (radios != null) { radios.CheckedChange += (sender, e) => { Items[position].IsCompleted = true; int radioButtonId = radios.CheckedRadioButtonId; View radioButton = radios.FindViewById(radioButtonId); int idx = radios.IndexOfChild(radioButton); Items[position].CompletionData.JsonData = idx.ToString(); NotifyItemChanged(Items.Count - 1); }; } } else if (thisType == typeof(TaskViewHolderMap)) { vh = holder as TaskViewHolderMap; TaskViewHolderMap mapHolder = ((TaskViewHolderMap)vh); if (taskType == "MAP_MARK") { List <Map_Location> points = JsonConvert.DeserializeObject <List <Map_Location> >(Items[position].CompletionData.JsonData); if (points != null && points.Count > 0) { if (mapHolder != null) { mapHolder.EnteredLocationsView.Visibility = ViewStates.Visible; mapHolder.EnteredLocationsView.Text = string.Format( context.Resources.GetString(Resource.String.ChosenLocations), points.Count, (points.Count > 1) ? "s" : ""); } Items[position].IsCompleted = true; } else { if (mapHolder != null) { mapHolder.EnteredLocationsView.Visibility = ViewStates.Gone; } Items[position].IsCompleted = false; } } } else { vh = holder as TaskViewHolder; } } // These apply to all task types: AndroidUtils.LoadTaskTypeIcon(Items[position].TaskType, ((TaskViewHolder)holder).TaskTypeIcon); if (!string.IsNullOrWhiteSpace(Items[position].ImageUrl)) { AndroidUtils.LoadActivityImageIntoView(vh.TaskImage, Items[position].ImageUrl, activityId, 350); } else { if (vh != null) { vh.TaskImage.Visibility = ViewStates.Gone; } } vh.Description.Text = Items[position].Description; vh.Title.Text = Items[position].TaskType.DisplayName; bool hasChildren = Items[position].ChildTasks != null && Items[position].ChildTasks.Any(); if (Items[position].TaskType.IdName == "ENTER_TEXT") { vh.LockedChildrenTease.Visibility = ViewStates.Gone; } else if (hasChildren && !Items[position].IsCompleted) { vh.LockedChildrenTease.Visibility = ViewStates.Visible; int childCount = Items[position].ChildTasks.Count(); vh.LockedChildrenTease.Text = string.Format( context.GetString(Resource.String.taskLockedParent), childCount, (childCount > 1) ? "s" : ""); } else if (hasChildren && Items[position].IsCompleted) { vh.LockedChildrenTease.Visibility = ViewStates.Visible; vh.LockedChildrenTease.Text = context.GetString(Resource.String.taskUnlockedParent); } else { vh.LockedChildrenTease.Visibility = ViewStates.Gone; } OnBind = false; }