diff --git a/app/build.gradle b/app/build.gradle
index 6b894348c..20d0d23c3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -194,7 +194,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
- implementation 'com.github.vanniktech:Emoji:0.6.0' // 0.7.0 has display issue - don't update to 0.7.0
+ // implementation 'com.github.vanniktech:Emoji:0.6.0' // 0.7.0 has display issue - don't update to 0.7.0
+ implementation "com.vanniktech:emoji-google:0.8.0"
+ // implementation "com.vanniktech:emoji-google-compat:0.8.0"
implementation group: 'androidx.emoji', name: 'emoji-bundled', version: '1.1.0'
implementation 'org.michaelevans.colorart:library:0.0.3'
implementation "androidx.work:work-runtime:${workVersion}"
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusClickListener.kt b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusClickListener.kt
new file mode 100644
index 000000000..fa2485dcd
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusClickListener.kt
@@ -0,0 +1,29 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.nextcloud.talk.adapters
+
+import com.nextcloud.talk.models.json.status.PredefinedStatus
+
+interface PredefinedStatusClickListener {
+ fun onClick(predefinedStatus: PredefinedStatus)
+}
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusListAdapter.kt b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusListAdapter.kt
new file mode 100644
index 000000000..253304af6
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusListAdapter.kt
@@ -0,0 +1,50 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.nextcloud.talk.adapters
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.nextcloud.talk.databinding.PredefinedStatusBinding
+import com.nextcloud.talk.models.json.status.PredefinedStatus
+
+class PredefinedStatusListAdapter(
+ private val clickListener: PredefinedStatusClickListener,
+ val context: Context
+) : RecyclerView.Adapter() {
+ internal var list: List = emptyList()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PredefinedStatusViewHolder {
+ val itemBinding = PredefinedStatusBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return PredefinedStatusViewHolder(itemBinding)
+ }
+
+ override fun onBindViewHolder(holder: PredefinedStatusViewHolder, position: Int) {
+ holder.bind(list[position], clickListener, context)
+ }
+
+ override fun getItemCount(): Int {
+ return list.size
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusViewHolder.kt
new file mode 100644
index 000000000..2671896c5
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/adapters/PredefinedStatusViewHolder.kt
@@ -0,0 +1,59 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.nextcloud.talk.adapters
+
+import android.content.Context
+import androidx.recyclerview.widget.RecyclerView
+import com.nextcloud.talk.R
+import com.nextcloud.talk.databinding.PredefinedStatusBinding
+import com.nextcloud.talk.models.json.status.PredefinedStatus
+import com.nextcloud.talk.utils.DisplayUtils
+
+private const val ONE_SECOND_IN_MILLIS = 1000
+
+class PredefinedStatusViewHolder(private val binding: PredefinedStatusBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(status: PredefinedStatus, clickListener: PredefinedStatusClickListener, context: Context) {
+ binding.root.setOnClickListener { clickListener.onClick(status) }
+ binding.icon.text = status.icon
+ binding.name.text = status.message
+
+ if (status.clearAt == null) {
+ binding.clearAt.text = context.getString(R.string.dontClear)
+ } else {
+ val clearAt = status.clearAt!!
+ if (clearAt.type.equals("period")) {
+ binding.clearAt.text = DisplayUtils.getRelativeTimestamp(
+ context,
+ System.currentTimeMillis() + clearAt.time.toInt() * ONE_SECOND_IN_MILLIS,
+ true
+ )
+ } else {
+ // end-of
+ if (clearAt.time.equals("day")) {
+ binding.clearAt.text = context.getString(R.string.today)
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java
index 74c17649a..e693731f3 100644
--- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java
+++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java
@@ -450,4 +450,9 @@ public interface NcApi {
*/
@GET
Observable status(@Header("Authorization") String authorization, @Url String url);
+
+ @DELETE
+ Observable statusDeleteMessage(@Header("Authorization") String authorization, @Url String url);
+
+
}
diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt
index 4c391d3b5..2ae6de462 100644
--- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt
+++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt
@@ -66,7 +66,7 @@ import com.nextcloud.talk.utils.database.user.UserModule
import com.nextcloud.talk.utils.preferences.AppPreferences
import com.nextcloud.talk.webrtc.MagicWebRTCUtils
import com.vanniktech.emoji.EmojiManager
-import com.vanniktech.emoji.googlecompat.GoogleCompatEmojiProvider
+import com.vanniktech.emoji.google.GoogleEmojiProvider
import de.cotech.hw.SecurityKeyManager
import de.cotech.hw.SecurityKeyManagerConfig
import okhttp3.OkHttpClient
@@ -188,7 +188,7 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver {
config.setReplaceAll(true)
val emojiCompat = EmojiCompat.init(config)
- EmojiManager.install(GoogleCompatEmojiProvider(emojiCompat))
+ EmojiManager.install(GoogleEmojiProvider())
NotificationUtils.registerNotificationChannels(applicationContext, appPreferences)
}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/status/ClearAt.kt b/app/src/main/java/com/nextcloud/talk/models/json/status/ClearAt.kt
new file mode 100644
index 000000000..aa6107447
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/models/json/status/ClearAt.kt
@@ -0,0 +1,4 @@
+package com.nextcloud.talk.models.json.status
+
+
+class ClearAt(val type: String, val time: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/status/PredefinedStatus.kt b/app/src/main/java/com/nextcloud/talk/models/json/status/PredefinedStatus.kt
new file mode 100644
index 000000000..0f689df2f
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/models/json/status/PredefinedStatus.kt
@@ -0,0 +1,3 @@
+package com.nextcloud.talk.models.json.status
+
+class PredefinedStatus(val id: String, val icon: String, val message: String, val clearAt: ClearAt?)
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/status/Status.java b/app/src/main/java/com/nextcloud/talk/models/json/status/Status.java
deleted file mode 100644
index d6f17d220..000000000
--- a/app/src/main/java/com/nextcloud/talk/models/json/status/Status.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- *
- * Nextcloud Talk application
- *
- * @author Tim Krüger
- * Copyright (C) 2021 Tim Krüger
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package com.nextcloud.talk.models.json.status;
-
-import com.bluelinelabs.logansquare.annotation.JsonField;
-import com.bluelinelabs.logansquare.annotation.JsonObject;
-
-import org.parceler.Parcel;
-
-import java.util.Objects;
-
-@Parcel
-@JsonObject
-public class Status {
-
- @JsonField(name = "userId")
- public String userId;
-
- @JsonField(name = "message")
- public String message;
-
- // TODO: Change to enum
- @JsonField(name = "messageId")
- public String messageId;
-
- @JsonField(name = "messageIsPredefined")
- public boolean messageIsPredefined;
-
- @JsonField(name = "icon")
- public String icon;
-
- @JsonField(name = "clearAt")
- public long clearAt;
-
- // TODO: Change to enum
- @JsonField(name = "status")
- public String status;
-
- @JsonField(name = "statusIsUserDefined")
- public boolean statusIsUserDefined;
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public String getMessageId() {
- return messageId;
- }
-
- public void setMessageId(String messageId) {
- this.messageId = messageId;
- }
-
- public boolean isMessageIsPredefined() {
- return messageIsPredefined;
- }
-
- public void setMessageIsPredefined(boolean messageIsPredefined) {
- this.messageIsPredefined = messageIsPredefined;
- }
-
- public String getIcon() {
- return icon;
- }
-
- public void setIcon(String icon) {
- this.icon = icon;
- }
-
- public long getClearAt() {
- return clearAt;
- }
-
- public void setClearAt(long clearAt) {
- this.clearAt = clearAt;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public boolean isStatusIsUserDefined() {
- return statusIsUserDefined;
- }
-
- public void setStatusIsUserDefined(boolean statusIsUserDefined) {
- this.statusIsUserDefined = statusIsUserDefined;
- }
-
- public String getUserId() {
- return this.userId;
- }
-
- public void setUserId(String userId) {
- this.userId = userId;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- Status status1 = (Status) o;
- return messageIsPredefined == status1.messageIsPredefined &&
- clearAt == status1.clearAt &&
- statusIsUserDefined == status1.statusIsUserDefined &&
- Objects.equals(userId, status1.userId) && Objects.equals(message, status1.message) &&
- Objects.equals(messageId, status1.messageId) && Objects.equals(icon, status1.icon) &&
- Objects.equals(status, status1.status);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(userId, message, messageId, messageIsPredefined, icon, clearAt, status, statusIsUserDefined);
- }
-
- @Override
- public String toString() {
- return "Status{" +
- "userId='" + userId + '\'' +
- ", message='" + message + '\'' +
- ", messageId='" + messageId + '\'' +
- ", messageIsPredefined=" + messageIsPredefined +
- ", icon='" + icon + '\'' +
- ", clearAt=" + clearAt +
- ", status='" + status + '\'' +
- ", statusIsUserDefined=" + statusIsUserDefined +
- '}';
- }
-}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/status/Status.kt b/app/src/main/java/com/nextcloud/talk/models/json/status/Status.kt
new file mode 100644
index 000000000..f66a09724
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/models/json/status/Status.kt
@@ -0,0 +1,52 @@
+/*
+ *
+ * Nextcloud Talk application
+ *
+ * @author Tim Krüger
+ * Copyright (C) 2021 Tim Krüger
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.talk.models.json.status
+
+import android.os.Parcelable
+import com.bluelinelabs.logansquare.annotation.JsonField
+import com.bluelinelabs.logansquare.annotation.JsonObject
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@JsonObject
+data class Status(
+ @JsonField(name = ["userId"])
+ var userId: String?,
+ @JsonField(name = ["message"])
+ var message: String?,
+ /* TODO: Change to enum */
+ @JsonField(name = ["messageId"])
+ var messageId: String?,
+ @JsonField(name = ["messageIsPredefined"])
+ var messageIsPredefined: Boolean,
+ @JsonField(name = ["icon"])
+ var icon: String?,
+ @JsonField(name = ["clearAt"])
+ var clearAt: Long = 0,
+ /* TODO: Change to enum */
+ @JsonField(name = ["status"])
+ var status: String = "offline",
+ @JsonField(name = ["statusIsUserDefined"])
+ var statusIsUserDefined: Boolean
+) : Parcelable {
+ // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
+ constructor() : this(null, null, null, false, null, 0, "offline", false)
+}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/status/StatusType.kt b/app/src/main/java/com/nextcloud/talk/models/json/status/StatusType.kt
new file mode 100644
index 000000000..3f11936de
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/models/json/status/StatusType.kt
@@ -0,0 +1,11 @@
+package com.nextcloud.talk.models.json.status
+
+
+
+enum class StatusType(val string: String) {
+ ONLINE("online"),
+ OFFLINE("offline"),
+ DND("dnd"),
+ AWAY("away"),
+ INVISIBLE("invisible");
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
index e497972e7..bdca62698 100644
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
@@ -47,6 +47,7 @@ import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.User;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.participants.Participant;
+import com.nextcloud.talk.models.json.status.Status;
import com.nextcloud.talk.models.json.status.StatusOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.DisplayUtils;
@@ -55,6 +56,7 @@ import com.nextcloud.talk.utils.database.user.UserUtils;
import java.net.CookieManager;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import javax.inject.Inject;
@@ -89,6 +91,8 @@ public class ChooseAccountDialogFragment extends DialogFragment {
private FlexibleAdapter adapter;
private final List userItems = new ArrayList<>();
+ private Status status;
+
@SuppressLint("InflateParams")
@NonNull
@Override
@@ -154,8 +158,12 @@ public class ChooseAccountDialogFragment extends DialogFragment {
binding.setStatus.setOnClickListener(v -> {
dismiss();
- SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(user);
- setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
+
+ // TODO: better solution
+ if(status != null) {
+ SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(user, status);
+ setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
+ }
});
if (CapabilitiesUtil.isUserStatusAvailable(userUtils.getCurrentUser())) {
@@ -200,28 +208,21 @@ public class ChooseAccountDialogFragment extends DialogFragment {
observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer() {
- private StatusOverall statusOverall;
-
@Override
- public void onSubscribe(@NonNull Disposable d) {
- Log.d("x", "onSubscribe");
- }
+ public void onSubscribe(@NonNull Disposable d) {}
@Override
public void onNext(@NonNull StatusOverall statusOverall) {
- Log.d("x", "onNext");
- this.statusOverall = statusOverall;
+ status = statusOverall.ocs.data;
}
@Override
public void onError(@NonNull Throwable e) {
- Log.e("x", "Läuft net", e);
+ Log.e(TAG, "Can't receive user status from server. ", e);
}
@Override
public void onComplete() {
- Log.d("x", "complete");
-
}
});
}
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
index 6ed134c93..94ee5aaf0 100644
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
@@ -22,17 +22,42 @@ package com.nextcloud.talk.ui.dialog
import android.annotation.SuppressLint
import android.app.Dialog
+import android.content.Context
import android.os.Bundle
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
+import android.widget.AdapterView
+import android.widget.AdapterView.OnItemSelectedListener
+import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import autodagger.AutoInjector
+import com.nextcloud.talk.R
+import com.nextcloud.talk.adapters.PredefinedStatusClickListener
+import com.nextcloud.talk.adapters.PredefinedStatusListAdapter
+import com.nextcloud.talk.api.NcApi
+import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.databinding.DialogSetStatusBinding
import com.nextcloud.talk.models.database.User
-import com.nextcloud.talk.models.json.status.StatusOverall
-import com.vanniktech.emoji.EmojiManager
-import com.vanniktech.emoji.google.GoogleEmojiProvider
+import com.nextcloud.talk.models.json.generic.GenericOverall
+import com.nextcloud.talk.models.json.status.ClearAt
+import com.nextcloud.talk.models.json.status.PredefinedStatus
+import com.nextcloud.talk.models.json.status.Status
+import com.nextcloud.talk.models.json.status.StatusType
+import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.DisplayUtils
+import com.vanniktech.emoji.EmojiPopup
+import io.reactivex.Observer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import java.util.Calendar
+import java.util.Locale
+import javax.inject.Inject
private const val ARG_CURRENT_USER_PARAM = "currentUser"
private const val ARG_CURRENT_STATUS_PARAM = "currentStatus"
@@ -52,19 +77,23 @@ private const val LAST_HOUR_OF_DAY = 23
private const val LAST_MINUTE_OF_HOUR = 59
private const val LAST_SECOND_OF_MINUTE = 59
+@AutoInjector(NextcloudTalkApplication::class)
class SetStatusDialogFragment :
- DialogFragment() {
+ DialogFragment(), PredefinedStatusClickListener {
+
+ private val logTag = ChooseAccountDialogFragment::class.java.simpleName
+
private lateinit var binding: DialogSetStatusBinding
- // private var currentUser: User? = null
- // private var currentStatus: Status? = null
+ private var currentUser: User? = null
+ private var currentStatus: Status? = null
// private lateinit var accountManager: UserAccountManager
- // private lateinit var predefinedStatus: ArrayList
- // private lateinit var adapter: PredefinedStatusListAdapter
- // private var selectedPredefinedMessageId: String? = null
- // private var clearAt: Long? = -1
- // private lateinit var popup: EmojiPopup
+ private lateinit var predefinedStatus: ArrayList
+ private lateinit var adapter: PredefinedStatusListAdapter
+ private var selectedPredefinedMessageId: String? = null
+ private var clearAt: Long? = -1
+ private lateinit var popup: EmojiPopup
//
// @Inject
// lateinit var arbitraryDataProvider: ArbitraryDataProvider
@@ -75,11 +104,14 @@ class SetStatusDialogFragment :
// @Inject
// lateinit var clientFactory: ClientFactory
+ @Inject
+ lateinit var ncApi: NcApi
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
- // currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
- // currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
+ currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
+ currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
// val json = arbitraryDataProvider.getValue(currentUser, ArbitraryDataProvider.PREDEFINED_STATUS)
@@ -91,7 +123,7 @@ class SetStatusDialogFragment :
- EmojiManager.install(GoogleEmojiProvider())
+ // EmojiManager.install(GoogleEmojiProvider())
}
@SuppressLint("InflateParams")
@@ -110,82 +142,85 @@ class SetStatusDialogFragment :
// accountManager = (activity as BaseActivity).userAccountManager
//
- // currentStatus?.let {
- // binding.emoji.setText(it.icon)
- // binding.customStatusInput.text?.clear()
- // binding.customStatusInput.setText(it.message)
- // visualizeStatus(it.status)
- //
- // if (it.clearAt > 0) {
- // binding.clearStatusAfterSpinner.visibility = View.GONE
- // binding.remainingClearTime.apply {
- // binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message)
- // visibility = View.VISIBLE
- // text = DisplayUtils.getRelativeTimestamp(context, it.clearAt * ONE_SECOND_IN_MILLIS, true)
- // .toString()
- // .decapitalize(Locale.getDefault())
- // setOnClickListener {
- // visibility = View.GONE
- // binding.clearStatusAfterSpinner.visibility = View.VISIBLE
- // binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message_after)
- // }
- // }
- // }
- // }
- //
- // adapter = PredefinedStatusListAdapter(this, requireContext())
- // if (this::predefinedStatus.isInitialized) {
- // adapter.list = predefinedStatus
- // }
- // binding.predefinedStatusList.adapter = adapter
- // binding.predefinedStatusList.layoutManager = LinearLayoutManager(context)
- //
- // binding.onlineStatus.setOnClickListener { setStatus(StatusType.ONLINE) }
- // binding.dndStatus.setOnClickListener { setStatus(StatusType.DND) }
- // binding.awayStatus.setOnClickListener { setStatus(StatusType.AWAY) }
- // binding.invisibleStatus.setOnClickListener { setStatus(StatusType.INVISIBLE) }
- //
- // binding.clearStatus.setOnClickListener { clearStatus() }
- // binding.setStatus.setOnClickListener { setStatusMessage() }
- // binding.emoji.setOnClickListener { openEmojiPopup() }
- //
- // popup = EmojiPopup.Builder
- // .fromRootView(view)
- // .setOnEmojiClickListener { _, _ ->
- // popup.dismiss()
- // binding.emoji.clearFocus()
- // val imm: InputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as
- // InputMethodManager
- // imm.hideSoftInputFromWindow(binding.emoji.windowToken, 0)
- // }
- // .build(binding.emoji)
- // binding.emoji.disableKeyboardInput(popup)
- // binding.emoji.forceSingleEmoji()
- //
- // val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item)
- // adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
- // adapter.add(getString(R.string.dontClear))
- // adapter.add(getString(R.string.thirtyMinutes))
- // adapter.add(getString(R.string.oneHour))
- // adapter.add(getString(R.string.fourHours))
- // adapter.add(getString(R.string.today))
- // adapter.add(getString(R.string.thisWeek))
- //
- // binding.clearStatusAfterSpinner.apply {
- // this.adapter = adapter
- // onItemSelectedListener = object : OnItemSelectedListener {
- // override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
- // setClearStatusAfterValue(position)
- // }
- //
- // override fun onNothingSelected(parent: AdapterView<*>?) {
- // // nothing to do
- // }
- // }
- // }
- //
- // binding.clearStatus.setTextColor(ThemeColorUtils.primaryColor(context, true))
+ currentStatus?.let {
+ binding.emoji.setText(it.icon)
+ binding.customStatusInput.text?.clear()
+ binding.customStatusInput.setText(it.message)
+ visualizeStatus(it.status)
+
+ if (it.clearAt > 0) {
+ binding.clearStatusAfterSpinner.visibility = View.GONE
+ binding.remainingClearTime.apply {
+ binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message)
+ visibility = View.VISIBLE
+ text = DisplayUtils.getRelativeTimestamp(context, it.clearAt * ONE_SECOND_IN_MILLIS, true)
+ .toString()
+ .decapitalize(Locale.getDefault())
+ setOnClickListener {
+ visibility = View.GONE
+ binding.clearStatusAfterSpinner.visibility = View.VISIBLE
+ binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message_after)
+ }
+ }
+ }
+ }
+
+ adapter = PredefinedStatusListAdapter(this, requireContext())
+ if (this::predefinedStatus.isInitialized) {
+ adapter.list = predefinedStatus
+ }
+ binding.predefinedStatusList.adapter = adapter
+ binding.predefinedStatusList.layoutManager = LinearLayoutManager(context)
+
+ binding.onlineStatus.setOnClickListener { setStatus(StatusType.ONLINE) }
+ binding.dndStatus.setOnClickListener { setStatus(StatusType.DND) }
+ binding.awayStatus.setOnClickListener { setStatus(StatusType.AWAY) }
+ binding.invisibleStatus.setOnClickListener { setStatus(StatusType.INVISIBLE) }
+
+ binding.clearStatus.setOnClickListener { clearStatus() }
+ binding.setStatus.setOnClickListener { setStatusMessage() }
+ binding.emoji.setOnClickListener { openEmojiPopup() }
+
+ popup = EmojiPopup.Builder
+ .fromRootView(view)
+ .setOnEmojiClickListener { _, _ ->
+ popup.dismiss()
+ binding.emoji.clearFocus()
+ val imm: InputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as
+ InputMethodManager
+ imm.hideSoftInputFromWindow(binding.emoji.windowToken, 0)
+ }
+ .build(binding.emoji)
+ binding.emoji.disableKeyboardInput(popup)
+ binding.emoji.forceSingleEmoji()
+
+ val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item)
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+ adapter.add(getString(R.string.dontClear))
+ adapter.add(getString(R.string.thirtyMinutes))
+ adapter.add(getString(R.string.oneHour))
+ adapter.add(getString(R.string.fourHours))
+ adapter.add(getString(R.string.today))
+ adapter.add(getString(R.string.thisWeek))
+
+ binding.clearStatusAfterSpinner.apply {
+ this.adapter = adapter
+ onItemSelectedListener = object : OnItemSelectedListener {
+ override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
+ setClearStatusAfterValue(position)
+ }
+
+ override fun onNothingSelected(parent: AdapterView<*>?) {
+ // nothing to do
+ }
+ }
+ }
+
+ binding.clearStatus.setTextColor(resources.getColor(R.color.colorPrimary))
+ binding.setStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
// ThemeButtonUtils.colorPrimaryButton(binding.setStatus, context)
+
+ binding.customStatusInput.highlightColor = resources.getColor(R.color.colorPrimary)
// ThemeTextInputUtils.colorTextInput(
// binding.customStatusInputContainer,
// binding.customStatusInput,
@@ -193,180 +228,202 @@ class SetStatusDialogFragment :
// )
}
- // @Suppress("ComplexMethod")
- // private fun setClearStatusAfterValue(item: Int) {
- // when (item) {
- // POS_DONT_CLEAR -> {
- // // don't clear
- // clearAt = null
- // }
- //
- // POS_HALF_AN_HOUR -> {
- // // 30 minutes
- // clearAt = System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + THIRTY_MINUTES * ONE_MINUTE_IN_SECONDS
- // }
- //
- // POS_AN_HOUR -> {
- // // one hour
- // clearAt =
- // System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + ONE_MINUTE_IN_SECONDS * ONE_MINUTE_IN_SECONDS
- // }
- //
- // POS_FOUR_HOURS -> {
- // // four hours
- // clearAt =
- // System.currentTimeMillis() / ONE_SECOND_IN_MILLIS
- // +FOUR_HOURS * ONE_MINUTE_IN_SECONDS * ONE_MINUTE_IN_SECONDS
- // }
- //
- // POS_TODAY -> {
- // // today
- // val date = Calendar.getInstance().apply {
- // set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
- // set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
- // set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
- // }
- // clearAt = date.timeInMillis / ONE_SECOND_IN_MILLIS
- // }
- //
- // POS_END_OF_WEEK -> {
- // // end of week
- // val date = Calendar.getInstance().apply {
- // set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
- // set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
- // set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
- // }
- //
- // while (date.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
- // date.add(Calendar.DAY_OF_YEAR, 1)
- // }
- //
- // clearAt = date.timeInMillis / ONE_SECOND_IN_MILLIS
- // }
- // }
- // }
- //
- // @Suppress("ReturnCount")
- // private fun clearAtToUnixTime(clearAt: ClearAt?): Long {
- // if (clearAt != null) {
- // if (clearAt.type.equals("period")) {
- // return System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + clearAt.time.toLong()
- // } else if (clearAt.type.equals("end-of")) {
- // if (clearAt.time.equals("day")) {
- // val date = Calendar.getInstance().apply {
- // set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
- // set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
- // set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
- // }
- // return date.timeInMillis / ONE_SECOND_IN_MILLIS
- // }
- // }
- // }
- //
- // return -1
- // }
- //
- // private fun openEmojiPopup() {
- // popup.show()
- // }
- //
- // private fun clearStatus() {
- // asyncRunner.postQuickTask(
- // ClearStatusTask(accountManager.currentOwnCloudAccount?.savedAccount, context),
- // { dismiss(it) }
- // )
- // }
- //
- // private fun setStatus(statusType: StatusType) {
- // visualizeStatus(statusType)
- //
- // asyncRunner.postQuickTask(
- // SetStatusTask(
- // statusType,
- // accountManager.currentOwnCloudAccount?.savedAccount,
- // context
- // ),
- // {
- // if (!it) {
- // clearTopStatus()
- // }
- // },
- // { clearTopStatus() }
- // )
- // }
- //
- // private fun visualizeStatus(statusType: StatusType) {
- // when (statusType) {
- // StatusType.ONLINE -> {
- // clearTopStatus()
- // binding.onlineStatus.setBackgroundColor(ThemeColorUtils.primaryColor(context))
- // }
- // StatusType.AWAY -> {
- // clearTopStatus()
- // binding.awayStatus.setBackgroundColor(ThemeColorUtils.primaryColor(context))
- // }
- // StatusType.DND -> {
- // clearTopStatus()
- // binding.dndStatus.setBackgroundColor(ThemeColorUtils.primaryColor(context))
- // }
- // StatusType.INVISIBLE -> {
- // clearTopStatus()
- // binding.invisibleStatus.setBackgroundColor(ThemeColorUtils.primaryColor(context))
- // }
- // else -> clearTopStatus()
- // }
- // }
- //
- // private fun clearTopStatus() {
- // context?.let {
- // val grey = it.resources.getColor(R.color.grey_200)
- // binding.onlineStatus.setBackgroundColor(grey)
- // binding.awayStatus.setBackgroundColor(grey)
- // binding.dndStatus.setBackgroundColor(grey)
- // binding.invisibleStatus.setBackgroundColor(grey)
- // }
- // }
- //
- // private fun setStatusMessage() {
- // if (selectedPredefinedMessageId != null) {
- // asyncRunner.postQuickTask(
- // SetPredefinedCustomStatusTask(
- // selectedPredefinedMessageId!!,
- // clearAt,
- // accountManager.currentOwnCloudAccount?.savedAccount,
- // context
- // ),
- // { dismiss(it) }
- // )
- // } else {
- // asyncRunner.postQuickTask(
- // SetUserDefinedCustomStatusTask(
- // binding.customStatusInput.text.toString(),
- // binding.emoji.text.toString(),
- // clearAt,
- // accountManager.currentOwnCloudAccount?.savedAccount,
- // context
- // ),
- // { dismiss(it) }
- // )
+ @Suppress("ComplexMethod")
+ private fun setClearStatusAfterValue(item: Int) {
+ when (item) {
+ POS_DONT_CLEAR -> {
+ // don't clear
+ clearAt = null
+ }
+
+ POS_HALF_AN_HOUR -> {
+ // 30 minutes
+ clearAt = System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + THIRTY_MINUTES * ONE_MINUTE_IN_SECONDS
+ }
+
+ POS_AN_HOUR -> {
+ // one hour
+ clearAt =
+ System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + ONE_MINUTE_IN_SECONDS * ONE_MINUTE_IN_SECONDS
+ }
+
+ POS_FOUR_HOURS -> {
+ // four hours
+ clearAt =
+ System.currentTimeMillis() / ONE_SECOND_IN_MILLIS
+ +FOUR_HOURS * ONE_MINUTE_IN_SECONDS * ONE_MINUTE_IN_SECONDS
+ }
+
+ POS_TODAY -> {
+ // today
+ val date = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
+ set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
+ set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
+ }
+ clearAt = date.timeInMillis / ONE_SECOND_IN_MILLIS
+ }
+
+ POS_END_OF_WEEK -> {
+ // end of week
+ val date = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
+ set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
+ set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
+ }
+
+ while (date.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
+ date.add(Calendar.DAY_OF_YEAR, 1)
+ }
+
+ clearAt = date.timeInMillis / ONE_SECOND_IN_MILLIS
+ }
+ }
+ }
+
+ @Suppress("ReturnCount")
+ private fun clearAtToUnixTime(clearAt: ClearAt?): Long {
+ if (clearAt != null) {
+ if (clearAt.type.equals("period")) {
+ return System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + clearAt.time.toLong()
+ } else if (clearAt.type.equals("end-of")) {
+ if (clearAt.time.equals("day")) {
+ val date = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, LAST_HOUR_OF_DAY)
+ set(Calendar.MINUTE, LAST_MINUTE_OF_HOUR)
+ set(Calendar.SECOND, LAST_SECOND_OF_MINUTE)
+ }
+ return date.timeInMillis / ONE_SECOND_IN_MILLIS
+ }
+ }
+ }
+
+ return -1
+ }
+
+ private fun openEmojiPopup() {
+ popup.show()
+ }
+
+
+ private fun clearStatus() {
+ // asyncRunner.postQuickTask(
+ // ClearStatusTask(accountManager.currentOwnCloudAccount?.savedAccount, context),
+ // { dismiss(it) }
+ // )
+
+ val credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
+ ncApi.statusDeleteMessage(credentials, ApiUtils.getUrlForStatus(currentUser?.baseUrl)).subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer {
+ override fun onSubscribe(d: Disposable) {}
+ override fun onNext(statusOverall: GenericOverall) {}
+ override fun onError(e: Throwable) {
+ Log.e(logTag, "Error removing attendee from conversation", e)
+ }
+ override fun onComplete() {
+ dismiss()
+ }
+ })
+ }
+
+ private fun setStatus(statusType: StatusType) {
+ visualizeStatus(statusType)
+
+ // asyncRunner.postQuickTask(
+ // SetStatusTask(
+ // statusType,
+ // accountManager.currentOwnCloudAccount?.savedAccount,
+ // context
+ // ),
+ // {
+ // if (!it) {
+ // clearTopStatus()
+ // }
+ // },
+ // { clearTopStatus() }
+ // )
+ }
+
+ private fun visualizeStatus(statusType: String) {
+ StatusType.values().firstOrNull { it.name == statusType.uppercase(Locale.ROOT) }?.let { visualizeStatus(it) }
+ }
+
+ private fun visualizeStatus(statusType: StatusType) {
+ when (statusType) {
+ StatusType.ONLINE -> {
+ clearTopStatus()
+ binding.onlineStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
+ }
+ StatusType.AWAY -> {
+ clearTopStatus()
+ binding.awayStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
+ }
+ StatusType.DND -> {
+ clearTopStatus()
+ binding.dndStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
+ }
+ StatusType.INVISIBLE -> {
+ clearTopStatus()
+ binding.invisibleStatus.setBackgroundColor(resources.getColor(R.color.colorPrimary))
+ }
+ else -> clearTopStatus()
+ }
+ }
+
+ private fun clearTopStatus() {
+ context?.let {
+ val grey = it.resources.getColor(R.color.grey_200)
+ binding.onlineStatus.setBackgroundColor(grey)
+ binding.awayStatus.setBackgroundColor(grey)
+ binding.dndStatus.setBackgroundColor(grey)
+ binding.invisibleStatus.setBackgroundColor(grey)
+ }
+ }
+
+
+ private fun setStatusMessage() {
+ // if (selectedPredefinedMessageId != null) {
+ // asyncRunner.postQuickTask(
+ // SetPredefinedCustomStatusTask(
+ // selectedPredefinedMessageId!!,
+ // clearAt,
+ // accountManager.currentOwnCloudAccount?.savedAccount,
+ // context
+ // ),
+ // { dismiss(it) }
+ // )
+ // } else {
+ // asyncRunner.postQuickTask(
+ // SetUserDefinedCustomStatusTask(
+ // binding.customStatusInput.text.toString(),
+ // binding.emoji.text.toString(),
+ // clearAt,
+ // accountManager.currentOwnCloudAccount?.savedAccount,
+ // context
+ // ),
+ // { dismiss(it) }
+ // )
+ // }
+ }
+
+ // private fun dismiss(boolean: Boolean) {
+ // if (boolean) {
+ // dismiss()
// }
// }
- private fun dismiss(boolean: Boolean) {
- if (boolean) {
- dismiss()
- }
- }
+
/**
* Fragment creator
*/
companion object {
@JvmStatic
- fun newInstance(user: User): SetStatusDialogFragment {
+ fun newInstance(user: User, status: Status): SetStatusDialogFragment {
val args = Bundle()
args.putParcelable(ARG_CURRENT_USER_PARAM, user)
- //args.putParcelable(ARG_CURRENT_STATUS_PARAM, status)
+ args.putParcelable(ARG_CURRENT_STATUS_PARAM, status)
+
val dialogFragment = SetStatusDialogFragment()
dialogFragment.arguments = args
@@ -379,42 +436,45 @@ class SetStatusDialogFragment :
return binding.root
}
- // override fun onClick(predefinedStatus: PredefinedStatus) {
- // selectedPredefinedMessageId = predefinedStatus.id
- // clearAt = clearAtToUnixTime(predefinedStatus.clearAt)
- // binding.emoji.setText(predefinedStatus.icon)
- // binding.customStatusInput.text?.clear()
- // binding.customStatusInput.text?.append(predefinedStatus.message)
- //
- // binding.remainingClearTime.visibility = View.GONE
- // binding.clearStatusAfterSpinner.visibility = View.VISIBLE
- // binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message_after)
- //
- // if (predefinedStatus.clearAt == null) {
- // binding.clearStatusAfterSpinner.setSelection(0)
- // } else {
- // val clearAt = predefinedStatus.clearAt!!
- // if (clearAt.type.equals("period")) {
- // when (clearAt.time) {
- // "1800" -> binding.clearStatusAfterSpinner.setSelection(POS_HALF_AN_HOUR)
- // "3600" -> binding.clearStatusAfterSpinner.setSelection(POS_AN_HOUR)
- // "14400" -> binding.clearStatusAfterSpinner.setSelection(POS_FOUR_HOURS)
- // else -> binding.clearStatusAfterSpinner.setSelection(POS_DONT_CLEAR)
- // }
- // } else if (clearAt.type.equals("end-of")) {
- // when (clearAt.time) {
- // "day" -> binding.clearStatusAfterSpinner.setSelection(POS_TODAY)
- // "week" -> binding.clearStatusAfterSpinner.setSelection(POS_END_OF_WEEK)
- // else -> binding.clearStatusAfterSpinner.setSelection(POS_DONT_CLEAR)
- // }
- // }
- // }
- // setClearStatusAfterValue(binding.clearStatusAfterSpinner.selectedItemPosition)
- // }
+ override fun onClick(predefinedStatus: PredefinedStatus) {
+ selectedPredefinedMessageId = predefinedStatus.id
+ clearAt = clearAtToUnixTime(predefinedStatus.clearAt)
+ binding.emoji.setText(predefinedStatus.icon)
+ binding.customStatusInput.text?.clear()
+ binding.customStatusInput.text?.append(predefinedStatus.message)
+
+ binding.remainingClearTime.visibility = View.GONE
+ binding.clearStatusAfterSpinner.visibility = View.VISIBLE
+ binding.clearStatusMessageTextView.text = getString(R.string.clear_status_message_after)
+
+ if (predefinedStatus.clearAt == null) {
+ binding.clearStatusAfterSpinner.setSelection(0)
+ } else {
+ val clearAt = predefinedStatus.clearAt!!
+ if (clearAt.type.equals("period")) {
+ when (clearAt.time) {
+ "1800" -> binding.clearStatusAfterSpinner.setSelection(POS_HALF_AN_HOUR)
+ "3600" -> binding.clearStatusAfterSpinner.setSelection(POS_AN_HOUR)
+ "14400" -> binding.clearStatusAfterSpinner.setSelection(POS_FOUR_HOURS)
+ else -> binding.clearStatusAfterSpinner.setSelection(POS_DONT_CLEAR)
+ }
+ } else if (clearAt.type.equals("end-of")) {
+ when (clearAt.time) {
+ "day" -> binding.clearStatusAfterSpinner.setSelection(POS_TODAY)
+ "week" -> binding.clearStatusAfterSpinner.setSelection(POS_END_OF_WEEK)
+ else -> binding.clearStatusAfterSpinner.setSelection(POS_DONT_CLEAR)
+ }
+ }
+ }
+ setClearStatusAfterValue(binding.clearStatusAfterSpinner.selectedItemPosition)
+ }
//
// @VisibleForTesting
// fun setPredefinedStatus(predefinedStatus: ArrayList) {
// adapter.list = predefinedStatus
// binding.predefinedStatusList.adapter?.notifyDataSetChanged()
// }
+
+
+
}
diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java
index 94ed1ac0d..227f25425 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java
+++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java
@@ -424,4 +424,8 @@ public class ApiUtils {
public static String getUrlForStatus(String baseUrl) {
return baseUrl + ocsApiVersion + "/apps/user_status/api/v1/user_status";
}
+
+ public static String getUrlForStatusMessage(String baseUrl) {
+ return getUrlForStatus(baseUrl) + "/message";
+ }
}
diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java
index 7309ad701..efcd91436 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java
+++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java
@@ -44,6 +44,7 @@ import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
+import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ClickableSpan;
@@ -86,6 +87,8 @@ import org.greenrobot.eventbus.EventBus;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
@@ -124,6 +127,8 @@ public class DisplayUtils {
private static final String HTTP_PROTOCOL = "http://";
private static final String HTTPS_PROTOCOL = "https://";
+ private static final int DATE_TIME_PARTS_SIZE = 2;
+
public static void setClickableString(String string, String url, TextView textView) {
SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(new ClickableSpan() {
@@ -605,4 +610,66 @@ public class DisplayUtils {
return R.string.menu_item_sort_by_name_a_z;
}
}
+
+ /**
+ * calculates the relative time string based on the given modification timestamp.
+ *
+ * @param context the app's context
+ * @param modificationTimestamp the UNIX timestamp of the file modification time in milliseconds.
+ * @return a relative time string
+ */
+
+ public static CharSequence getRelativeTimestamp(Context context, long modificationTimestamp, boolean showFuture) {
+ return getRelativeDateTimeString(context,
+ modificationTimestamp,
+ android.text.format.DateUtils.SECOND_IN_MILLIS,
+ DateUtils.WEEK_IN_MILLIS,
+ 0,
+ showFuture);
+ }
+
+ public static CharSequence getRelativeDateTimeString(Context c,
+ long time,
+ long minResolution,
+ long transitionResolution,
+ int flags,
+ boolean showFuture) {
+
+ CharSequence dateString = "";
+
+ // in Future
+ if (!showFuture && time > System.currentTimeMillis()) {
+ return DisplayUtils.unixTimeToHumanReadable(time);
+ }
+ // < 60 seconds -> seconds ago
+ long diff = System.currentTimeMillis() - time;
+ if (diff > 0 && diff < 60 * 1000 && minResolution == DateUtils.SECOND_IN_MILLIS) {
+ return c.getString(R.string.secondsAgo);
+ } else {
+ dateString = DateUtils.getRelativeDateTimeString(c, time, minResolution, transitionResolution, flags);
+ }
+
+ String[] parts = dateString.toString().split(",");
+ if (parts.length == DATE_TIME_PARTS_SIZE) {
+ if (parts[1].contains(":") && !parts[0].contains(":")) {
+ return parts[0];
+ } else if (parts[0].contains(":") && !parts[1].contains(":")) {
+ return parts[1];
+ }
+ }
+ // dateString contains unexpected format. fallback: use relative date time string from android api as is.
+ return dateString.toString();
+ }
+
+ /**
+ * Converts Unix time to human readable format
+ *
+ * @param milliseconds that have passed since 01/01/1970
+ * @return The human readable time for the users locale
+ */
+ public static String unixTimeToHumanReadable(long milliseconds) {
+ Date date = new Date(milliseconds);
+ DateFormat df = DateFormat.getDateTimeInstance();
+ return df.format(date);
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 05c9d63d2..95d700d88 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -288,6 +288,7 @@
1 hour
4 hours
This week
+ seconds ago
Unread mentions