commit
e9eb7e6bf6
15 changed files with 702 additions and 179 deletions
67
OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml
Normal file
67
OsmAnd-telegram/res/layout/bottom_sheet_sharing_status.xml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:layout_gravity="bottom">
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
android:id="@+id/scroll_view_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_view_bottom_padding">
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_bg_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:text="@string/sharing_status"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/list_item_title_text_size"
|
||||
app:firstBaselineToTopHeight="28sp"
|
||||
app:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/items_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/card_bg_color">
|
||||
|
||||
<include
|
||||
layout="@layout/secondary_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding_half" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -50,10 +50,10 @@
|
|||
android:id="@+id/text_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/content_padding_standard"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/my_location_text_sides_margin"
|
||||
android:layout_marginBottom="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/my_location_text_sides_margin">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -157,6 +157,7 @@
|
|||
android:gravity="center_vertical">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/status_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/action_bar_height"
|
||||
android:layout_weight="1"
|
||||
|
@ -166,20 +167,18 @@
|
|||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:text="@string/my_location"
|
||||
android:textColor="@color/app_bar_title_light"
|
||||
android:textSize="@dimen/title_text_size"
|
||||
app:typeface="@string/font_roboto_mono_bold" />
|
||||
app:typeface="@string/font_roboto_mono_bold"
|
||||
tools:text="@string/sharing_enabled" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/options_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
tools:src="@drawable/ic_action_other_menu"
|
||||
tools:tint="@color/icon_light"
|
||||
tools:visibility="visible" />
|
||||
|
@ -198,8 +197,15 @@
|
|||
android:id="@+id/stop_all_sharing_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_height"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stop_all_sharing_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard">
|
||||
|
||||
|
@ -207,23 +213,84 @@
|
|||
android:id="@+id/stop_all_sharing_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/stop_sharing_all"
|
||||
android:text="@string/shared_string_disable"
|
||||
android:textColor="?attr/ctrl_active_color"
|
||||
android:textSize="@dimen/descr_text_size"
|
||||
android:textSize="@dimen/hint_text_size"
|
||||
app:lastBaselineToBottomHeight="24dp"
|
||||
app:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/stop_all_sharing_switcher"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"/>
|
||||
android:focusable="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/appbar_divider2"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/card_divider_color" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/sharing_status_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sharing_status_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_marginTop="@dimen/content_padding_standard"
|
||||
tools:src="@drawable/ic_action_live_now"
|
||||
tools:tint="@color/ctrl_active_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shared_string_status"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/list_item_description_text_size"
|
||||
app:typeface="@string/font_roboto_regular" />
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/sharing_status_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/ctrl_active_color"
|
||||
android:textSize="@dimen/hint_text_size"
|
||||
app:lastBaselineToBottomHeight="@dimen/content_padding_standard"
|
||||
app:typeface="@string/font_roboto_medium"
|
||||
tools:text="@string/no_gps_connection" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -231,11 +298,10 @@
|
|||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
|
@ -258,9 +324,9 @@
|
|||
android:paddingRight="32dp"
|
||||
android:text="@string/share_location"
|
||||
android:textColor="@color/white"
|
||||
app:typeface="@string/font_roboto_medium"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
app:typeface="@string/font_roboto_medium"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
|
121
OsmAnd-telegram/res/layout/item_with_three_text_lines.xml
Normal file
121
OsmAnd-telegram/res/layout/item_with_three_text_lines.xml
Normal file
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_marginTop="@dimen/content_padding_standard"
|
||||
tools:src="@drawable/ic_action_wifi_off"
|
||||
tools:tint="@color/icon_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/list_item_title_text_size"
|
||||
app:firstBaselineToTopHeight="28sp"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
tools:text="@string/no_internet_connection" />
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/status_change_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/list_item_description_text_size"
|
||||
app:firstBaselineToTopHeight="26sp"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
tools:text="14:30" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/description_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/last_location_line"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/list_item_description_text_size"
|
||||
app:firstBaselineToTopHeight="22dp"
|
||||
app:lastBaselineToBottomHeight="20dp"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
tools:text="@string/last_available_location" />
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/last_location_line_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/list_item_description_text_size"
|
||||
app:firstBaselineToTopHeight="22dp"
|
||||
app:lastBaselineToBottomHeight="20dp"
|
||||
app:typeface="@string/font_roboto_medium"
|
||||
tools:text="14:24" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:id="@+id/re_send_location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/list_item_height"
|
||||
android:paddingRight="@dimen/list_item_height"
|
||||
android:text="@string/re_send_location"
|
||||
android:textColor="?attr/ctrl_active_color"
|
||||
android:textSize="@dimen/hint_text_size"
|
||||
app:lastBaselineToBottomHeight="16dp"
|
||||
app:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="@dimen/list_item_height"
|
||||
android:layout_marginStart="@dimen/list_item_height"
|
||||
android:background="?attr/card_divider_color" />
|
||||
|
||||
</LinearLayout>
|
|
@ -38,4 +38,7 @@
|
|||
|
||||
<color name="app_bar_title_light">#333333</color>
|
||||
|
||||
<color name="sharing_status_icon_error">#ee5622</color>
|
||||
<color name="sharing_status_icon_success">#78cc5c</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
<resources>
|
||||
<string name="re_send_location">Re-send location</string>
|
||||
<string name="last_sent_location">Last sent location</string>
|
||||
<string name="last_available_location">Last available location</string>
|
||||
<string name="sharing_status">Sharing status</string>
|
||||
<string name="sharing_enabled">Sharing: Enabled</string>
|
||||
<string name="shared_string_status">Status</string>
|
||||
<string name="no_gps_connection">No GPS connection</string>
|
||||
<string name="sharing_success">Successfully sent and updated</string>
|
||||
<string name="not_possible_to_send_to_chats">Not possible to send to chats:</string>
|
||||
<string name="no_internet_connection">No internet connection</string>
|
||||
<string name="shared_string_disable">Disable</string>
|
||||
<string name="shared_string_save">Save</string>
|
||||
<string name="add_device_descr">Enter your device id that you can find at https://live.osmand.net/device/ID</string>
|
||||
<string name="device_id">Device id</string>
|
||||
|
|
|
@ -232,7 +232,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
}
|
||||
|
||||
override fun onLocationChanged(l: Location?) {
|
||||
if (l != null) {
|
||||
val location = convertLocation(l)
|
||||
if (!isContinuous()) {
|
||||
// unregister listener and wait next time
|
||||
|
@ -253,7 +252,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
app().shareLocationHelper.updateLocation(location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProviderDisabled(provider: String) {
|
||||
Toast.makeText(this, getString(R.string.location_service_no_gps_available), Toast.LENGTH_LONG).show()
|
||||
|
@ -296,6 +294,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
|
||||
|
|
|
@ -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<Long, ShareChatInfo>()
|
||||
private var shareChatsInfo = ConcurrentHashMap<Long, ShareChatInfo>()
|
||||
private var hiddenOnMapChats: Set<Long> = emptySet()
|
||||
|
||||
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
||||
|
||||
var shareDevicesIds = mutableMapOf<String, String>()
|
||||
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,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
hiddenChats.intersect(presentChatIds)
|
||||
hiddenOnMapChats = hiddenChats.toHashSet()
|
||||
|
||||
shareChatsInfo = shareChatsInfo.filter { (key, _) ->
|
||||
presentChatIds.contains(key)
|
||||
}.toMutableMap()
|
||||
shareChatsInfo = ConcurrentHashMap(shareChatsInfo.filter { (key, _) -> presentChatIds.contains(key) })
|
||||
}
|
||||
|
||||
fun shareLocationToChat(
|
||||
|
@ -123,14 +128,14 @@ 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
|
||||
}
|
||||
shareChatInfo.userSetLivePeriod = lp
|
||||
shareChatInfo.userSetLivePeriodStart = currentTime
|
||||
shareChatInfo.currentMessageLimit = currentTime +
|
||||
Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
shareChatInfo.currentMessageLimit = currentTime + Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
shareChatInfo.additionalActiveTime = addActiveTime
|
||||
shareChatsInfo[chatId] = shareChatInfo
|
||||
} else {
|
||||
|
@ -149,14 +154,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
fun getChatsShareInfo() = shareChatsInfo
|
||||
|
||||
fun getChatLiveMessageExpireTime(chatId: Long): Long {
|
||||
val shareInfo = shareChatsInfo[chatId]
|
||||
return if (shareInfo != null) {
|
||||
shareInfo.userSetLivePeriod - ((System.currentTimeMillis() / 1000) - shareInfo.start)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1
|
||||
|
||||
fun stopSharingLocationToChats() {
|
||||
shareChatsInfo.clear()
|
||||
|
@ -193,9 +191,56 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
val shareChatInfo = shareChatsInfo[message.chatId]
|
||||
val content = message.content
|
||||
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
||||
shareChatInfo.start = message.date.toLong()
|
||||
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) {
|
||||
locationTime = getLastSuccessfulSendTime()
|
||||
SharingStatusType.NO_INTERNET
|
||||
} else if (app.shareLocationHelper.lastLocation == null) {
|
||||
locationTime = app.shareLocationHelper.lastLocationMessageSentTime
|
||||
SharingStatusType.NO_GPS
|
||||
} else {
|
||||
var sendChatsErrors = false
|
||||
shareChatsInfo.forEach { _, shareInfo ->
|
||||
if (shareInfo.hasSharingError) {
|
||||
sendChatsErrors = true
|
||||
locationTime = shareInfo.lastSuccessfulSendTimeMs
|
||||
val title = app.telegramHelper.getChat(shareInfo.chatId)?.title
|
||||
if (title != null) {
|
||||
chatsTitles.add(title)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sendChatsErrors) {
|
||||
SharingStatusType.NOT_POSSIBLE_TO_SENT_TO_CHATS
|
||||
} else {
|
||||
locationTime = getLastSuccessfulSendTime()
|
||||
SharingStatusType.SUCCESSFULLY_SENT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 +498,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 +544,30 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
var data: String = ""
|
||||
}
|
||||
|
||||
class SharingStatus {
|
||||
var locationTime: Long = -1
|
||||
var statusChangeTime: Long = -1
|
||||
var chatsTitles: MutableList<String> = 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,9 +578,10 @@ 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]
|
||||
var hasSharingError = false
|
||||
|
||||
fun getNextAdditionalActiveTime(): Long {
|
||||
var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime)
|
||||
|
@ -485,6 +592,10 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getChatLiveMessageExpireTime(): Long {
|
||||
return userSetLivePeriod - ((System.currentTimeMillis() / 1000) - start)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal const val CHAT_ID_KEY = "chatId"
|
||||
|
|
|
@ -23,9 +23,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
|
||||
var lastLocationMessageSentTime: Long = 0
|
||||
|
||||
private var lastTimeInMillis: Long = 0L
|
||||
|
||||
private var lastLocation: Location? = null
|
||||
var lastLocation: Location? = null
|
||||
set(value) {
|
||||
if (lastTimeInMillis == 0L) {
|
||||
lastTimeInMillis = System.currentTimeMillis()
|
||||
|
@ -40,6 +38,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
field = value
|
||||
}
|
||||
|
||||
private var lastTimeInMillis: Long = 0L
|
||||
|
||||
fun updateLocation(location: Location?) {
|
||||
lastLocation = location
|
||||
|
||||
|
@ -54,19 +54,20 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
val url = "https://live.osmand.net/device/$sharingMode/send?lat=${location.latitude}&lon=${location.longitude}"
|
||||
AndroidNetworkUtils.sendRequestAsync(url, null)
|
||||
}
|
||||
}
|
||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
app.settings.updateSharingStatusHistory()
|
||||
refreshNotification()
|
||||
}
|
||||
|
||||
fun updateSendLiveMessages() {
|
||||
log.info("updateSendLiveMessages")
|
||||
if (app.settings.hasAnyChatToShareLocation()) {
|
||||
app.settings.getChatsShareInfo().forEach { chatId, shareInfo ->
|
||||
val currentTime = System.currentTimeMillis() / 1000
|
||||
when {
|
||||
app.settings.getChatLiveMessageExpireTime(chatId) <= 0 ->
|
||||
app.settings.shareLocationToChat(chatId, false)
|
||||
shareInfo.getChatLiveMessageExpireTime() <= 0 -> app.settings.shareLocationToChat(chatId, false)
|
||||
currentTime > shareInfo.currentMessageLimit -> {
|
||||
shareInfo.apply {
|
||||
val newLivePeriod =
|
||||
|
@ -77,8 +78,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
livePeriod = newLivePeriod
|
||||
shouldDeletePreviousMessage = true
|
||||
currentMessageLimit = currentTime + Math.min(
|
||||
newLivePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
currentMessageLimit = currentTime + Math.min(newLivePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
}
|
||||
}
|
||||
shareInfo.userSetLivePeriod != shareInfo.livePeriod
|
||||
|
@ -86,13 +86,14 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
shareInfo.apply {
|
||||
shouldDeletePreviousMessage = true
|
||||
livePeriod = shareInfo.userSetLivePeriod
|
||||
currentMessageLimit = currentTime + Math.min(
|
||||
livePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong()
|
||||
)
|
||||
currentMessageLimit = currentTime + Math.min(livePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stopSharingLocation()
|
||||
}
|
||||
}
|
||||
|
||||
fun startSharingLocation() {
|
||||
|
|
|
@ -28,6 +28,7 @@ class TelegramHelper private constructor() {
|
|||
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
||||
private const val CHATS_LIMIT = 100
|
||||
private const val IGNORED_ERROR_CODE = 406
|
||||
private const val MESSAGE_CANNOT_BE_EDITED_ERROR_CODE = 5
|
||||
|
||||
private const val DEVICE_PREFIX = "Device: "
|
||||
private const val LOCATION_PREFIX = "Location: "
|
||||
|
@ -97,7 +98,6 @@ class TelegramHelper private constructor() {
|
|||
private var haveAuthorization = false
|
||||
|
||||
private val defaultHandler = DefaultHandler()
|
||||
private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
|
||||
|
||||
private var updateLiveMessagesExecutor: ScheduledExecutorService? = null
|
||||
|
||||
|
@ -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<TdApi.Message>)
|
||||
fun onDeleteMessages(chatId: Long, messages: List<Long>)
|
||||
fun onSendLiveLocationError(code: Int, message: String)
|
||||
}
|
||||
|
||||
interface FullInfoUpdatesListener {
|
||||
|
@ -595,19 +595,19 @@ class TelegramHelper private constructor() {
|
|||
return false
|
||||
}
|
||||
|
||||
fun stopSendingLiveLocationToChat(chatId: Long, msgId: Long) {
|
||||
if (msgId != -1L) {
|
||||
fun stopSendingLiveLocationToChat(shareInfo: TelegramSettings.ShareChatInfo) {
|
||||
if (shareInfo.currentMessageId != -1L && shareInfo.chatId != -1L) {
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, null),
|
||||
liveLocationMessageUpdatesHandler
|
||||
)
|
||||
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMessageId, null, null)) { obj ->
|
||||
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||
}
|
||||
}
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
}
|
||||
|
||||
fun stopSendingLiveLocationMessages(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>) {
|
||||
chatsShareInfo.forEach { (chatId, chatInfo) ->
|
||||
stopSendingLiveLocationToChat(chatId, chatInfo.currentMessageId)
|
||||
chatsShareInfo.forEach { (_, chatInfo) ->
|
||||
stopSendingLiveLocationToChat(chatInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,27 +633,29 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
private fun recreateLiveLocationMessage(chatId: Long, msgId: Long, content: TdApi.InputMessageLocation) {
|
||||
if (msgId != -1L) {
|
||||
log.info("recreateLiveLocationMessage - $msgId")
|
||||
private fun recreateLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageLocation) {
|
||||
if (shareInfo.currentMessageId != -1L && shareInfo.chatId != -1L) {
|
||||
log.info("recreateLiveLocationMessage - $shareInfo.currentMessageId")
|
||||
val array = LongArray(1)
|
||||
array[0] = msgId
|
||||
client?.send(TdApi.DeleteMessages(chatId, array, true)) { obj ->
|
||||
array[0] = shareInfo.currentMessageId
|
||||
client?.send(TdApi.DeleteMessages(shareInfo.chatId, array, true)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Ok.CONSTRUCTOR -> {
|
||||
sendNewLiveLocationMessage(chatId, content)
|
||||
}
|
||||
TdApi.Ok.CONSTRUCTOR -> sendNewLiveLocationMessage(shareInfo, content)
|
||||
TdApi.Error.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -660,18 +664,21 @@ class TelegramHelper private constructor() {
|
|||
needRefreshActiveLiveLocationMessages = true
|
||||
}
|
||||
|
||||
private fun sendNewLiveLocationMessage(chatId: Long, content: TdApi.InputMessageLocation) {
|
||||
private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageLocation) {
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
log.info("sendNewLiveLocationMessage")
|
||||
client?.send(
|
||||
TdApi.SendMessage(chatId, 0, false, true, null, content),
|
||||
liveLocationMessageUpdatesHandler
|
||||
)
|
||||
TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendLiveLocationImpl(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, latitude: Double, longitude: Double) {
|
||||
val location = TdApi.Location(latitude, longitude)
|
||||
chatsShareInfo.forEach { (chatId, shareInfo) ->
|
||||
if (shareInfo.getChatLiveMessageExpireTime() <= 0) {
|
||||
return@forEach
|
||||
}
|
||||
val livePeriod =
|
||||
if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
||||
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||
|
@ -682,18 +689,51 @@ class TelegramHelper private constructor() {
|
|||
val msgId = shareInfo.currentMessageId
|
||||
if (msgId != -1L) {
|
||||
if (shareInfo.shouldDeletePreviousMessage) {
|
||||
recreateLiveLocationMessage(chatId, msgId, content)
|
||||
recreateLiveLocationMessage(shareInfo, content)
|
||||
shareInfo.shouldDeletePreviousMessage = false
|
||||
shareInfo.currentMessageId = -1
|
||||
} else {
|
||||
log.info("EditMessageLiveLocation - $msgId")
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, location),
|
||||
liveLocationMessageUpdatesHandler
|
||||
)
|
||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, location)) { obj ->
|
||||
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sendNewLiveLocationMessage(chatId, content)
|
||||
sendNewLiveLocationMessage(shareInfo, content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLiveLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo) {
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
|
||||
shareInfo.shouldDeletePreviousMessage = true
|
||||
} else if (error.code != IGNORED_ERROR_CODE) {
|
||||
shareInfo.hasSharingError = true
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onSendLiveLocationError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
TdApi.Message.CONSTRUCTOR -> {
|
||||
if (obj is TdApi.Message) {
|
||||
if (obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
|
||||
shareInfo.hasSharingError = true
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send")
|
||||
}
|
||||
} else {
|
||||
shareInfo.hasSharingError = false
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onUpdateMessages(listOf(obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -751,32 +791,6 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private inner class LiveLocationMessageUpdatesHandler : ResultHandler {
|
||||
override fun onResult(obj: TdApi.Object) {
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
listener?.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")
|
||||
} else {
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onUpdateMessages(listOf(obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onAuthorizationStateUpdated(authorizationState: AuthorizationState?, info: Boolean = false) {
|
||||
val prevAuthState = getTelegramAuthorizationState()
|
||||
if (authorizationState != null) {
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
@ -132,6 +135,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
AndroidUtils.addStatusBarPadding19v(context, this)
|
||||
}
|
||||
|
||||
mainView.findViewById<TextView>(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
|
||||
}
|
||||
|
||||
mainView.findViewById<ImageView>(R.id.sharing_status_icon).setImageDrawable(app.uiUtils.getActiveIcon(R.drawable.ic_action_live_now))
|
||||
|
||||
textContainer = mainView.findViewById<LinearLayout>(R.id.text_container).apply {
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
|
||||
|
@ -181,8 +194,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
}
|
||||
|
||||
mainView.findViewById<View>(R.id.sharing_status_container).setOnClickListener {
|
||||
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<View>(R.id.start_sharing_btn).apply {
|
||||
visibility = if (sharingMode) View.VISIBLE else View.GONE
|
||||
setOnClickListener {
|
||||
|
@ -227,6 +248,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
app.stopSharingLocation()
|
||||
updateContent()
|
||||
}
|
||||
SharingStatusBottomSheet.SHARING_STATUS_REQUEST_CODE -> {
|
||||
updateSharingStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,9 +293,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
|
||||
|
@ -394,6 +415,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
private fun updateContent() {
|
||||
sharingMode = sharingMode && settings.hasAnyChatToShareLocation()
|
||||
updateSharingStatus()
|
||||
updateSharingMode()
|
||||
updateList()
|
||||
}
|
||||
|
@ -409,10 +432,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
appBarScrollRange = -1
|
||||
}
|
||||
|
||||
private fun updateSharingStatus() {
|
||||
if (sharingMode && settings.sharingStatusChanges.isNotEmpty()) {
|
||||
sharingStatusDescription.text = settings.sharingStatusChanges.last().getDescription(app)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateList() {
|
||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||
val currentUser = telegramHelper.getCurrentUser()
|
||||
val chatList = if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
||||
val chatList = if (sharingMode) {
|
||||
settings.getShareLocationChats()
|
||||
} else {
|
||||
telegramHelper.getChatListIds()
|
||||
|
@ -520,10 +549,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
isChecked = live
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
if (!isChecked) {
|
||||
val currentMessageId = shareInfo?.currentMessageId
|
||||
settings.shareLocationToChat(chat.id, false)
|
||||
if (currentMessageId != null) {
|
||||
telegramHelper.stopSendingLiveLocationToChat(chat.id, currentMessageId)
|
||||
if (shareInfo != null) {
|
||||
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
||||
}
|
||||
removeItem(chat)
|
||||
}
|
||||
|
@ -539,14 +567,15 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
}
|
||||
|
||||
val expiresIn = settings.getChatLiveMessageExpireTime(chat.id)
|
||||
val expiresIn = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
|
||||
holder.textInArea?.apply {
|
||||
val time = shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
visibility = View.VISIBLE
|
||||
text = "${getText(R.string.plus)} ${OsmandFormatter.getFormattedDuration(context!!, time)}"
|
||||
setOnClickListener {
|
||||
val newLivePeriod = settings.getChatLiveMessageExpireTime(chat.id) + (shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0])
|
||||
val expireTime = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
val newLivePeriod = expireTime + (shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0])
|
||||
val nextAdditionalActiveTime = shareInfo?.getNextAdditionalActiveTime() ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[1]
|
||||
settings.shareLocationToChat(chat.id, true, newLivePeriod, nextAdditionalActiveTime)
|
||||
notifyItemChanged(position)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
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.LinearLayout
|
||||
import android.widget.TextView
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
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<View>(R.id.scroll_view_container).setOnClickListener { dismiss() }
|
||||
BottomSheetBehavior.from(mainView.findViewById<View>(R.id.scroll_view))
|
||||
.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
|
||||
targetFragment?.also { target ->
|
||||
target.onActivityResult(targetRequestCode, SHARING_STATUS_REQUEST_CODE, null)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {}
|
||||
})
|
||||
|
||||
val itemsCont = mainView.findViewById<ViewGroup>(R.id.items_container)
|
||||
settings.sharingStatusChanges.reversed().forEach { sharingStatus ->
|
||||
inflater.inflate(R.layout.item_with_three_text_lines, itemsCont, false).apply {
|
||||
val sharingStatusType = sharingStatus.statusType
|
||||
val time = sharingStatus.locationTime
|
||||
|
||||
findViewById<ImageView>(R.id.icon).setImageDrawable(uiUtils.getIcon(sharingStatusType.iconId, sharingStatusType.iconColorRes))
|
||||
findViewById<TextView>(R.id.title).text = sharingStatus.getDescription(app)
|
||||
findViewById<TextView>(R.id.status_change_time).text = OsmandFormatter.getFormattedTime(sharingStatus.statusChangeTime, false)
|
||||
findViewById<TextView>(R.id.last_location_line).text = getString(sharingStatusType.descriptionId)
|
||||
|
||||
if (time > 0) {
|
||||
findViewById<TextView>(R.id.last_location_line_time).text = OsmandFormatter.getFormattedTime(time, false)
|
||||
} else {
|
||||
findViewById<LinearLayout>(R.id.description_container).visibility = View.INVISIBLE
|
||||
}
|
||||
if (sharingStatusType.canResendLocation) {
|
||||
findViewById<TextView>(R.id.re_send_location).apply {
|
||||
setOnClickListener {
|
||||
app.forceUpdateMyLocation()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
findViewById<TextView>(R.id.re_send_location).visibility = View.GONE
|
||||
}
|
||||
itemsCont.addView(this)
|
||||
}
|
||||
}
|
||||
mainView.findViewById<TextView>(R.id.secondary_btn).apply {
|
||||
setText(R.string.shared_string_close)
|
||||
setOnClickListener {
|
||||
targetFragment?.also { target ->
|
||||
target.onActivityResult(targetRequestCode, SHARING_STATUS_REQUEST_CODE, null)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue