Пример #1
0
        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;
            }
        }
Пример #2
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);
        }
Пример #3
0
        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();
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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;
        }
Пример #9
0
        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);
        }
Пример #10
0
        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;
            }
        }
Пример #11
0
        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;
        }