From 0ff05fd0a69fb1e19bf74db0ae3cb3ade8c1e403 Mon Sep 17 00:00:00 2001 From: Chumva Date: Fri, 12 Oct 2018 19:17:38 +0300 Subject: [PATCH] Telegram sharing status init --- .../layout/bottom_sheet_sharing_status.xml | 67 ++++++++ .../res/layout/fragment_my_location_tab.xml | 144 +++++++++++++----- .../res/layout/item_with_four_text_lines.xml | 106 +++++++++++++ OsmAnd-telegram/res/values/colors.xml | 3 + OsmAnd-telegram/res/values/strings.xml | 11 ++ .../telegram/TelegramLocationProvider.kt | 4 + .../net/osmand/telegram/TelegramService.kt | 5 + .../net/osmand/telegram/TelegramSettings.kt | 137 ++++++++++++++++- .../osmand/telegram/helpers/TelegramHelper.kt | 22 ++- .../osmand/telegram/ui/LiveNowTabFragment.kt | 2 - .../net/osmand/telegram/ui/MainActivity.kt | 8 - .../telegram/ui/MyLocationTabFragment.kt | 49 ++++-- .../telegram/ui/SharingStatusBottomSheet.kt | 97 ++++++++++++ .../osmand/telegram/utils/OsmandFormatter.kt | 10 +- .../src/net/osmand/telegram/utils/UiUtils.kt | 4 + 15 files changed, 595 insertions(+), 74 deletions(-) create mode 100644 OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml create mode 100644 OsmAnd-telegram/res/layout/item_with_four_text_lines.xml create mode 100644 OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt diff --git a/OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml b/OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml new file mode 100644 index 0000000000..c8504c9e9e --- /dev/null +++ b/OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd-telegram/res/layout/fragment_my_location_tab.xml b/OsmAnd-telegram/res/layout/fragment_my_location_tab.xml index edfe03a4c2..260bddf8a3 100644 --- a/OsmAnd-telegram/res/layout/fragment_my_location_tab.xml +++ b/OsmAnd-telegram/res/layout/fragment_my_location_tab.xml @@ -1,6 +1,5 @@ - + android:paddingRight="@dimen/my_location_text_sides_margin" + android:visibility="gone"> + app:typeface="@string/font_roboto_mono_bold" + tools:text="@string/sharing_enabled"/> + tools:visibility="visible"/> @@ -192,38 +192,106 @@ android:layout_height="1dp" android:layout_marginLeft="@dimen/content_padding_standard" android:layout_marginStart="@dimen/content_padding_standard" - android:background="?attr/card_divider_color" /> + android:background="?attr/card_divider_color"/> + android:gravity="center_vertical"> - + android:background="?attr/selectableItemBackground" + android:orientation="horizontal" + android:paddingLeft="@dimen/content_padding_standard" + android:paddingRight="@dimen/content_padding_standard"> - + + + + + + + + + + + + + + + + + + + + + @@ -231,11 +299,11 @@ - + tools:visibility="gone"> - + diff --git a/OsmAnd-telegram/res/layout/item_with_four_text_lines.xml b/OsmAnd-telegram/res/layout/item_with_four_text_lines.xml new file mode 100644 index 0000000000..9c42bb2a35 --- /dev/null +++ b/OsmAnd-telegram/res/layout/item_with_four_text_lines.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd-telegram/res/values/colors.xml b/OsmAnd-telegram/res/values/colors.xml index 708f542586..a7ecf7ec06 100644 --- a/OsmAnd-telegram/res/values/colors.xml +++ b/OsmAnd-telegram/res/values/colors.xml @@ -38,4 +38,7 @@ #333333 + #ee5622 + #78cc5c + diff --git a/OsmAnd-telegram/res/values/strings.xml b/OsmAnd-telegram/res/values/strings.xml index a5d4631d6c..e773d6bb22 100644 --- a/OsmAnd-telegram/res/values/strings.xml +++ b/OsmAnd-telegram/res/values/strings.xml @@ -1,4 +1,15 @@ + Re-send location + Last sent location + Last available location + Sharing status + Sharing: Enabled + Status + No GPS connection + Successfully sent and updated + Not possible to send to chats: + No internet connection + Disable Save Enter your device id that you can find at https://live.osmand.net/device/ID Device id diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt index 18bf39723a..daa1b71242 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramLocationProvider.kt @@ -45,6 +45,9 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve var lastKnownLocation: net.osmand.Location? = null private set + var lastKnownLocationTime: Long? = null + private set + val gpsInfo = GPSInfo() private val locationListeners = ArrayList() @@ -432,6 +435,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve updateGPSInfo(null) } if (location != null) { + lastKnownLocationTime = location.time if (gpsSignalLost) { gpsSignalLost = false } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt index fdb8c97897..b74cf7bc41 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt @@ -180,6 +180,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis updateShareInfoHandler?.postDelayed({ if (isUsedByMyLocation(usedBy)) { app().shareLocationHelper.updateSendLiveMessages() + app().settings.updateSharingStatusHistory() startShareInfoUpdates() } }, UPDATE_LIVE_MESSAGES_INTERVAL_MS) @@ -296,6 +297,10 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis app().settings.onDeleteLiveMessages(chatId, messages) } + override fun onSendLiveLocationError(code: Int, message: String) { + Log.d(PlatformUtil.TAG, "Send live location error: $code - $message") + } + companion object { const val USED_BY_MY_LOCATION: Int = 1 diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index 4c87c3d684..175fbc734d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -1,8 +1,11 @@ package net.osmand.telegram import android.content.Context +import android.support.annotation.ColorRes import android.support.annotation.DrawableRes import android.support.annotation.StringRes +import android.text.SpannableStringBuilder +import android.text.style.ForegroundColorSpan import net.osmand.data.LatLon import net.osmand.telegram.helpers.OsmandAidlHelper import net.osmand.telegram.helpers.TelegramHelper @@ -14,6 +17,8 @@ import org.drinkless.td.libcore.telegram.TdApi import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentLinkedQueue val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180 * 60L) @@ -64,9 +69,11 @@ private const val SHARE_CHATS_INFO_KEY = "share_chats_info" class TelegramSettings(private val app: TelegramApplication) { - private var shareChatsInfo = mutableMapOf() + private var shareChatsInfo = ConcurrentHashMap() private var hiddenOnMapChats: Set = emptySet() + var sharingStatusChanges = ConcurrentLinkedQueue() + var shareDevicesIds = mutableMapOf() var currentSharingMode = "" @@ -91,7 +98,7 @@ class TelegramSettings(private val app: TelegramApplication) { fun hasAnyChatToShareLocation() = shareChatsInfo.isNotEmpty() - fun isSharingLocationToChat(chatId: Long) = shareChatsInfo.contains(chatId) + fun isSharingLocationToChat(chatId: Long) = shareChatsInfo.containsKey(chatId) fun hasAnyChatToShowOnMap() = !hiddenOnMapChats.containsAll(getLiveNowChats()) @@ -102,9 +109,9 @@ class TelegramSettings(private val app: TelegramApplication) { hiddenChats.intersect(presentChatIds) hiddenOnMapChats = hiddenChats.toHashSet() - shareChatsInfo = shareChatsInfo.filter { (key, _) -> + shareChatsInfo = ConcurrentHashMap(shareChatsInfo.filter { (key, _) -> presentChatIds.contains(key) - }.toMutableMap() + }) } fun shareLocationToChat( @@ -123,6 +130,7 @@ class TelegramSettings(private val app: TelegramApplication) { shareChatInfo = ShareChatInfo() } val currentTime = System.currentTimeMillis() / 1000 + shareChatInfo.chatId = chatId shareChatInfo.start = currentTime if (shareChatInfo.livePeriod == -1L) { shareChatInfo.livePeriod = lp @@ -149,6 +157,8 @@ class TelegramSettings(private val app: TelegramApplication) { fun getChatsShareInfo() = shareChatsInfo + fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1 + fun getChatLiveMessageExpireTime(chatId: Long): Long { val shareInfo = shareChatsInfo[chatId] return if (shareInfo != null) { @@ -195,7 +205,56 @@ class TelegramSettings(private val app: TelegramApplication) { if (shareChatInfo != null && content is TdApi.MessageLocation) { shareChatInfo.currentMessageId = message.id shareChatInfo.lastSuccessfulLocation = LatLon(content.location.latitude, content.location.longitude) - shareChatInfo.lastSuccessfulSendTime = Math.max(message.editDate, message.date).toLong() + shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * + 1000L + } + } + + fun updateSharingStatusHistory() { + val newSharingStatus = SharingStatus().apply { + statusChangeTime = System.currentTimeMillis() + statusType = if (!app.isInternetConnectionAvailable) { + SharingStatusType.NO_INTERNET + } else if (app.locationProvider.lastKnownLocation == null || !app.locationProvider.gpsInfo.fixed) { + SharingStatusType.NO_GPS + } else { + var sendChatErrors = false + shareChatsInfo.forEach { _, shareInfo -> + if ((statusChangeTime - shareInfo.lastSuccessfulSendTimeMs) > (sendMyLocInterval * 2) * 1000) { + sendChatErrors = true + locationTime = shareInfo.lastSuccessfulSendTimeMs + val title = app.telegramHelper.getChat(shareInfo.chatId)?.title + if (title != null) { + chatsTitles.add(title) + } + } + } + if (sendChatErrors) { + SharingStatusType.NOT_POSSIBLE_TO_SENT_TO_CHATS + } else { + SharingStatusType.SUCCESSFULLY_SENT + } + } + if (statusType == SharingStatusType.NO_INTERNET || statusType == SharingStatusType.SUCCESSFULLY_SENT) { + locationTime = getLastSuccessfulSendTime() + } else if (statusType == SharingStatusType.NO_GPS) { + locationTime = app.locationProvider.lastKnownLocationTime ?: -1 + } + } + + if (sharingStatusChanges.isNotEmpty()) { + val lastSharingStatus = sharingStatusChanges.last() + if (lastSharingStatus.statusType != newSharingStatus.statusType) { + sharingStatusChanges.add(newSharingStatus) + } else { + lastSharingStatus.apply { + statusChangeTime = newSharingStatus.statusChangeTime + locationTime = newSharingStatus.locationTime + chatsTitles = newSharingStatus.chatsTitles + } + } + } else { + sharingStatusChanges.add(newSharingStatus) } } @@ -453,6 +512,43 @@ class TelegramSettings(private val app: TelegramApplication) { fun isSortByGroup() = this == SORT_BY_GROUP } + enum class SharingStatusType( + @DrawableRes val iconId: Int, + @ColorRes val iconColorRes: Int, + @StringRes val titleId: Int, + @StringRes val descriptionId: Int, + val canResendLocation: Boolean + ) { + NO_INTERNET( + R.drawable.ic_action_wifi_off, + R.color.sharing_status_icon_error, + R.string.no_internet_connection, + R.string.last_sent_location, + true + ), + SUCCESSFULLY_SENT( + R.drawable.ic_action_share_location, + R.color.sharing_status_icon_success, + R.string.sharing_success, + R.string.last_sent_location, + false + ), + NOT_POSSIBLE_TO_SENT_TO_CHATS( + R.drawable.ic_action_message_send_error, + R.color.sharing_status_icon_error, + R.string.not_possible_to_send_to_chats, + R.string.last_sent_location, + true + ), + NO_GPS( + R.drawable.ic_action_location_off, + R.color.sharing_status_icon_error, + R.string.no_gps_connection, + R.string.last_available_location, + false + ); + } + class DeviceBot { var id: Long = -1 var userId: Long = -1 @@ -462,6 +558,35 @@ class TelegramSettings(private val app: TelegramApplication) { var data: String = "" } + class SharingStatus { + var locationTime: Long = -1 + var statusChangeTime: Long = -1 + var chatsTitles: MutableList = mutableListOf() + lateinit var statusType: SharingStatusType + + fun getDescription(app: TelegramApplication): CharSequence { + return if (statusType != SharingStatusType.NOT_POSSIBLE_TO_SENT_TO_CHATS || chatsTitles.isEmpty()) { + app.getString(statusType.titleId) + } else { + val spannableString = SpannableStringBuilder(app.getString(statusType.titleId)) + val iterator = chatsTitles.iterator() + while (iterator.hasNext()) { + val chatTitle = iterator.next() + val start = spannableString.length + val newSpannable = if (iterator.hasNext()) " @$chatTitle," else " @$chatTitle." + spannableString.append(newSpannable) + spannableString.setSpan( + ForegroundColorSpan(app.uiUtils.getActiveColor()), + start, + spannableString.length - 1, + 0 + ) + } + spannableString + } + } + } + class ShareChatInfo { var chatId = -1L @@ -472,7 +597,7 @@ class TelegramSettings(private val app: TelegramApplication) { var userSetLivePeriod = -1L var userSetLivePeriodStart = -1L var lastSuccessfulLocation: LatLon? = null - var lastSuccessfulSendTime = -1L + var lastSuccessfulSendTimeMs = -1L var shouldDeletePreviousMessage = false var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0] diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index db8d6a860b..ba67e21cdd 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -234,7 +234,6 @@ class TelegramHelper private constructor() { fun onTelegramChatChanged(chat: TdApi.Chat) fun onTelegramUserChanged(user: TdApi.User) fun onTelegramError(code: Int, message: String) - fun onSendLiveLocationError(code: Int, message: String) } interface TelegramIncomingMessagesListener { @@ -246,6 +245,7 @@ class TelegramHelper private constructor() { interface TelegramOutgoingMessagesListener { fun onUpdateMessages(messages: List) fun onDeleteMessages(chatId: Long, messages: List) + fun onSendLiveLocationError(code: Int, message: String) } interface FullInfoUpdatesListener { @@ -619,7 +619,9 @@ class TelegramHelper private constructor() { val error = obj as TdApi.Error if (error.code != IGNORED_ERROR_CODE) { needRefreshActiveLiveLocationMessages = true - listener?.onSendLiveLocationError(error.code, error.message) + outgoingMessagesListeners.forEach { + it.onSendLiveLocationError(error.code, error.message) + } } } TdApi.Messages.CONSTRUCTOR -> { @@ -631,7 +633,9 @@ class TelegramHelper private constructor() { } onComplete?.invoke() } - else -> listener?.onSendLiveLocationError(-1, "Receive wrong response from TDLib: $obj") + else -> outgoingMessagesListeners.forEach { + it.onSendLiveLocationError(-1, "Receive wrong response from TDLib: $obj") + } } requestingActiveLiveLocationMessages = false } @@ -651,7 +655,9 @@ class TelegramHelper private constructor() { val error = obj as TdApi.Error if (error.code != IGNORED_ERROR_CODE) { needRefreshActiveLiveLocationMessages = true - listener?.onSendLiveLocationError(error.code, error.message) + outgoingMessagesListeners.forEach { + it.onSendLiveLocationError(error.code, error.message) + } } } } @@ -758,14 +764,18 @@ class TelegramHelper private constructor() { val error = obj as TdApi.Error if (error.code != IGNORED_ERROR_CODE) { needRefreshActiveLiveLocationMessages = true - listener?.onSendLiveLocationError(error.code, error.message) + outgoingMessagesListeners.forEach { + it.onSendLiveLocationError(error.code, error.message) + } } } TdApi.Message.CONSTRUCTOR -> { if (obj is TdApi.Message) { if (obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) { needRefreshActiveLiveLocationMessages = true - listener?.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send") + outgoingMessagesListeners.forEach { + it.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send") + } } else { outgoingMessagesListeners.forEach { it.onUpdateMessages(listOf(obj)) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt index 14e9b82c14..2157e9d17a 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt @@ -170,8 +170,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage override fun onTelegramError(code: Int, message: String) {} - override fun onSendLiveLocationError(code: Int, message: String) {} - override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) { app.runInUIThread { updateList() } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt index 14cf76596b..9d372ca24d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt @@ -275,14 +275,6 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene } } - override fun onSendLiveLocationError(code: Int, message: String) { - log.error("Send live location error: $code - $message") - app.isInternetConnectionAvailable(true) - runOnUi { - listeners.forEach { it.get()?.onSendLiveLocationError(code, message) } - } - } - override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) { addGrayPhoto(chatId) if (!app.showLocationHelper.showingLocation && settings.hasAnyChatToShowOnMap()) { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt index 477e3fc047..c15f4bbcc2 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt @@ -12,6 +12,8 @@ import android.support.v4.app.Fragment import android.support.v4.content.ContextCompat import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView +import android.text.SpannableString +import android.text.style.ForegroundColorSpan import android.view.* import android.view.animation.LinearInterpolator import android.widget.* @@ -57,6 +59,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { private lateinit var description: TextView private lateinit var searchBox: FrameLayout private lateinit var stopSharingSwitcher: Switch + private lateinit var sharingStatusDescription: TextView private lateinit var startSharingBtn: View private lateinit var searchBoxBg: GradientDrawable @@ -71,7 +74,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { private var actionButtonsListener: ActionButtonsListener? = null private var sharingMode = false - + private var updateEnable: Boolean = false override fun onCreateView( @@ -90,7 +93,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { searchBoxSidesMargin = resources.getDimensionPixelSize(R.dimen.content_padding_half) sharingMode = settings.hasAnyChatToShareLocation() - + savedInstanceState?.apply { selectedChats.addAll(getLongArray(SELECTED_CHATS_KEY).toSet()) if (selectedChats.isNotEmpty()) { @@ -132,6 +135,14 @@ class MyLocationTabFragment : Fragment(), TelegramListener { AndroidUtils.addStatusBarPadding19v(context, this) } + mainView.findViewById(R.id.status_title).apply { + val sharingStatus = getString(R.string.sharing_enabled) + val spannable = SpannableString(sharingStatus) + spannable.setSpan(ForegroundColorSpan(app.uiUtils.getActiveColor()), + sharingStatus.indexOf(" "), sharingStatus.length, 0) + text = spannable + } + textContainer = mainView.findViewById(R.id.text_container).apply { if (Build.VERSION.SDK_INT >= 16) { layoutTransition.enableTransitionType(LayoutTransition.CHANGING) @@ -181,8 +192,17 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } } + mainView.findViewById(R.id.sharing_status_container).setOnClickListener { + settings.updateSharingStatusHistory() + fragmentManager?.also { fm -> + SharingStatusBottomSheet.showInstance(fm, this) + } + } + stopSharingSwitcher = mainView.findViewById(R.id.stop_all_sharing_switcher) + sharingStatusDescription = mainView.findViewById(R.id.sharing_status_description) + startSharingBtn = mainView.findViewById(R.id.start_sharing_btn).apply { visibility = if (sharingMode) View.VISIBLE else View.GONE setOnClickListener { @@ -191,7 +211,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { updateContent() } } - + return mainView } @@ -208,7 +228,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { super.onPause() updateEnable = false } - + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLongArray(SELECTED_CHATS_KEY, selectedChats.toLongArray()) @@ -269,9 +289,6 @@ class MyLocationTabFragment : Fragment(), TelegramListener { override fun onTelegramError(code: Int, message: String) { } - override fun onSendLiveLocationError(code: Int, message: String) { - } - fun onPrimaryBtnClick() { if (selectedChats.isNotEmpty()) { val fm = fragmentManager ?: return @@ -306,7 +323,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } }, ADAPTER_UPDATE_INTERVAL_MIL) } - + private fun animateStartSharingBtn(show: Boolean) { if (startSharingBtn.visibility == View.VISIBLE) { val scale = if (show) 1f else 0f @@ -318,7 +335,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { .start() } } - + private fun clearSelection() { selectedChats.clear() adapter.notifyDataSetChanged() @@ -394,6 +411,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } private fun updateContent() { + updateSharingStatus() updateSharingMode() updateList() } @@ -409,6 +427,15 @@ class MyLocationTabFragment : Fragment(), TelegramListener { appBarScrollRange = -1 } + private fun updateSharingStatus() { + if (sharingMode) { + if (settings.sharingStatusChanges.isEmpty()) { + settings.updateSharingStatusHistory() + } + sharingStatusDescription.text = settings.sharingStatusChanges.last().getDescription(app) + } + } + private fun updateList() { val chats: MutableList = mutableListOf() val currentUser = telegramHelper.getCurrentUser() @@ -441,7 +468,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { list.sortWith(Comparator { o1, o2 -> o1.title.compareTo(o2.title) }) return list } - + inner class MyLocationListAdapter : RecyclerView.Adapter() { var chats = mutableListOf() set(value) { @@ -540,7 +567,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } val expiresIn = settings.getChatLiveMessageExpireTime(chat.id) - + holder.textInArea?.apply { val time = shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0] visibility = View.VISIBLE diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt new file mode 100644 index 0000000000..955d10b033 --- /dev/null +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt @@ -0,0 +1,97 @@ +package net.osmand.telegram.ui + +import android.os.Bundle +import android.support.design.widget.BottomSheetBehavior +import android.support.v4.app.DialogFragment +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import net.osmand.telegram.R +import net.osmand.telegram.TelegramApplication +import net.osmand.telegram.TelegramSettings +import net.osmand.telegram.ui.views.BottomSheetDialog +import net.osmand.telegram.utils.OsmandFormatter + +class SharingStatusBottomSheet : DialogFragment() { + private val app: TelegramApplication + get() = activity?.application as TelegramApplication + private val settings get() = app.settings + private val uiUtils get() = app.uiUtils + + override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(context!!) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val mainView = inflater.inflate(R.layout.bottom_sheet_sharing_status, container, false) + mainView.findViewById(R.id.scroll_view_container).setOnClickListener { dismiss() } + BottomSheetBehavior.from(mainView.findViewById(R.id.scroll_view)) + .setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { + override fun onStateChanged(bottomSheet: View, newState: Int) { + if (newState == BottomSheetBehavior.STATE_HIDDEN) { + dismiss() + } + } + + override fun onSlide(bottomSheet: View, slideOffset: Float) {} + }) + + val itemsCont = mainView.findViewById(R.id.items_container) + settings.sharingStatusChanges.reversed().forEach { sharingStatus -> + inflater.inflate(R.layout.item_with_four_text_lines, itemsCont, false).apply { + val sharingStatusType = sharingStatus.statusType + findViewById(R.id.icon).setImageDrawable(uiUtils.getIcon(sharingStatusType.iconId, sharingStatusType.iconColorRes)) + findViewById(R.id.title).text = sharingStatus.getDescription(app) + findViewById(R.id.status_change_time).text = + OsmandFormatter.getFormattedTime(sharingStatus.statusChangeTime, false) + val time = sharingStatus.locationTime + findViewById(R.id.last_location_line).text = getString(sharingStatusType.descriptionId) + if (time > 0) { + val sentTime = OsmandFormatter.getFormattedTime(time, false) + findViewById(R.id.last_location_line_time).text = sentTime + } else { + findViewById(R.id.last_location_line_time).text = "-" + } + if (sharingStatusType.canResendLocation) { + findViewById(R.id.re_send_location).apply { + setOnClickListener { + app.forceUpdateMyLocation() + dismiss() + } + } + } else { + findViewById(R.id.re_send_location).visibility = View.GONE + } + itemsCont.addView(this) + } + } + + mainView.findViewById(R.id.secondary_btn).apply { + setText(R.string.shared_string_close) + setOnClickListener { dismiss() } + } + return mainView + } + + companion object { + const val SHARING_STATUS_REQUEST_CODE = 5 + private const val TAG = "SharingStatusBottomSheet" + fun showInstance(fm: FragmentManager, target: Fragment): Boolean { + return try { + SharingStatusBottomSheet().apply { + setTargetFragment(target, SHARING_STATUS_REQUEST_CODE) + show(fm, TAG) + } + true + } catch (e: RuntimeException) { + false + } + } + } +} \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt index 371d91b657..803fd2f4be 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt @@ -21,7 +21,7 @@ object OsmandFormatter { private val fixed1 = DecimalFormat("0.0") private const val SHORT_TIME_FORMAT = "%02d:%02d" - private const val SIMPLE_TIME_OF_DAY_FORMAT = "HH:mm" + private const val SIMPLE_TIME_OF_DAY_FORMAT = "HH:mm:ss" private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss" private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60 @@ -62,9 +62,13 @@ object OsmandFormatter { } } - fun getFormattedTime(seconds: Long): String { + fun getFormattedTime(milliseconds: Long, useCurrentTime: Boolean = true): String { val calendar = Calendar.getInstance() - calendar.timeInMillis = System.currentTimeMillis() + (seconds * 1000) + if (useCurrentTime) { + calendar.timeInMillis = System.currentTimeMillis() + milliseconds + } else { + calendar.timeInMillis = milliseconds + } return if (isSameDay(calendar, Calendar.getInstance())) { SimpleDateFormat(SIMPLE_TIME_OF_DAY_FORMAT, Locale.getDefault()).format(calendar.time) } else { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt index 23bf249b1b..111d8ca2fb 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/UiUtils.kt @@ -107,6 +107,10 @@ class UiUtils(private val app: TelegramApplication) { return getDrawable(id, if (isLightContent) R.color.ctrl_active_light else 0) } + fun getActiveColor():Int { + return ContextCompat.getColor(app, if (isLightContent) R.color.ctrl_active_light else 0) + } + fun getIcon(@DrawableRes id: Int): Drawable? { return getDrawable(id, 0) }