Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
04f079381a
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:id="@+id/text_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_standard"
|
||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="@dimen/my_location_text_sides_margin"
|
android:paddingLeft="@dimen/my_location_text_sides_margin"
|
||||||
android:layout_marginBottom="@dimen/content_padding_standard"
|
|
||||||
android:paddingRight="@dimen/my_location_text_sides_margin">
|
android:paddingRight="@dimen/my_location_text_sides_margin">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -157,6 +157,7 @@
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<net.osmand.telegram.ui.views.TextViewEx
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/status_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="@dimen/action_bar_height"
|
android:layout_height="@dimen/action_bar_height"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
@ -166,20 +167,18 @@
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:paddingLeft="@dimen/content_padding_standard"
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
android:paddingRight="@dimen/content_padding_standard"
|
android:paddingRight="@dimen/content_padding_standard"
|
||||||
android:text="@string/my_location"
|
|
||||||
android:textColor="@color/app_bar_title_light"
|
android:textColor="@color/app_bar_title_light"
|
||||||
android:textSize="@dimen/title_text_size"
|
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
|
<ImageView
|
||||||
android:id="@+id/options_title"
|
android:id="@+id/options_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
|
||||||
android:layout_marginRight="@dimen/content_padding_standard"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:paddingLeft="@dimen/content_padding_half"
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
android:paddingRight="@dimen/content_padding_half"
|
android:paddingRight="@dimen/content_padding_standard"
|
||||||
tools:src="@drawable/ic_action_other_menu"
|
tools:src="@drawable/ic_action_other_menu"
|
||||||
tools:tint="@color/icon_light"
|
tools:tint="@color/icon_light"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
@ -198,32 +197,100 @@
|
||||||
android:id="@+id/stop_all_sharing_row"
|
android:id="@+id/stop_all_sharing_row"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/action_bar_height"
|
android:layout_height="@dimen/action_bar_height"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:gravity="center_vertical">
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingLeft="@dimen/content_padding_standard"
|
|
||||||
android:paddingRight="@dimen/content_padding_standard">
|
|
||||||
|
|
||||||
<net.osmand.telegram.ui.views.TextViewEx
|
<LinearLayout
|
||||||
android:id="@+id/stop_all_sharing_title"
|
android:id="@+id/stop_all_sharing_container"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
|
||||||
android:layout_marginRight="@dimen/content_padding_standard"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:ellipsize="end"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:maxLines="1"
|
android:orientation="horizontal"
|
||||||
android:text="@string/stop_sharing_all"
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
android:textColor="?attr/ctrl_active_color"
|
android:paddingRight="@dimen/content_padding_standard">
|
||||||
android:textSize="@dimen/descr_text_size"
|
|
||||||
app:typeface="@string/font_roboto_medium" />
|
|
||||||
|
|
||||||
<Switch
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
android:id="@+id/stop_all_sharing_switcher"
|
android:id="@+id/stop_all_sharing_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@null"
|
android:layout_gravity="bottom"
|
||||||
android:clickable="false"
|
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||||
android:focusable="false"/>
|
android:layout_marginRight="@dimen/content_padding_standard"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/shared_string_disable"
|
||||||
|
android:textColor="?attr/ctrl_active_color"
|
||||||
|
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" />
|
||||||
|
|
||||||
|
</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>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -231,11 +298,10 @@
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
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.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
|
@ -258,9 +324,9 @@
|
||||||
android:paddingRight="32dp"
|
android:paddingRight="32dp"
|
||||||
android:text="@string/share_location"
|
android:text="@string/share_location"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
app:typeface="@string/font_roboto_medium"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible"/>
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</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="app_bar_title_light">#333333</color>
|
||||||
|
|
||||||
|
<color name="sharing_status_icon_error">#ee5622</color>
|
||||||
|
<color name="sharing_status_icon_success">#78cc5c</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
<resources>
|
<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="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="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>
|
<string name="device_id">Device id</string>
|
||||||
|
|
|
@ -232,26 +232,24 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationChanged(l: Location?) {
|
override fun onLocationChanged(l: Location?) {
|
||||||
if (l != null) {
|
val location = convertLocation(l)
|
||||||
val location = convertLocation(l)
|
if (!isContinuous()) {
|
||||||
if (!isContinuous()) {
|
// unregister listener and wait next time
|
||||||
// unregister listener and wait next time
|
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
try {
|
||||||
try {
|
locationManager.removeUpdates(this)
|
||||||
locationManager.removeUpdates(this)
|
} catch (e: Throwable) {
|
||||||
} catch (e: Throwable) {
|
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
|
||||||
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
val lock = getLock(this)
|
|
||||||
if (lock.isHeld) {
|
|
||||||
lock.release()
|
|
||||||
}
|
|
||||||
app().shareLocationHelper.updateLocation(location)
|
|
||||||
} else if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
|
|
||||||
lastLocationSentTime = System.currentTimeMillis()
|
|
||||||
app().shareLocationHelper.updateLocation(location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lock = getLock(this)
|
||||||
|
if (lock.isHeld) {
|
||||||
|
lock.release()
|
||||||
|
}
|
||||||
|
app().shareLocationHelper.updateLocation(location)
|
||||||
|
} else if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
|
||||||
|
lastLocationSentTime = System.currentTimeMillis()
|
||||||
|
app().shareLocationHelper.updateLocation(location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +294,10 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
||||||
app().settings.onDeleteLiveMessages(chatId, messages)
|
app().settings.onDeleteLiveMessages(chatId, messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSendLiveLocationError(code: Int, message: String) {
|
||||||
|
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val USED_BY_MY_LOCATION: Int = 1
|
const val USED_BY_MY_LOCATION: Int = 1
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package net.osmand.telegram
|
package net.osmand.telegram
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.support.annotation.ColorRes
|
||||||
import android.support.annotation.DrawableRes
|
import android.support.annotation.DrawableRes
|
||||||
import android.support.annotation.StringRes
|
import android.support.annotation.StringRes
|
||||||
|
import android.text.SpannableStringBuilder
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
import net.osmand.data.LatLon
|
import net.osmand.data.LatLon
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
|
@ -14,6 +17,8 @@ import org.drinkless.td.libcore.telegram.TdApi
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
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)
|
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) {
|
class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
private var shareChatsInfo = mutableMapOf<Long, ShareChatInfo>()
|
private var shareChatsInfo = ConcurrentHashMap<Long, ShareChatInfo>()
|
||||||
private var hiddenOnMapChats: Set<Long> = emptySet()
|
private var hiddenOnMapChats: Set<Long> = emptySet()
|
||||||
|
|
||||||
|
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
||||||
|
|
||||||
var shareDevicesIds = mutableMapOf<String, String>()
|
var shareDevicesIds = mutableMapOf<String, String>()
|
||||||
var currentSharingMode = ""
|
var currentSharingMode = ""
|
||||||
|
|
||||||
|
@ -91,7 +98,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
fun hasAnyChatToShareLocation() = shareChatsInfo.isNotEmpty()
|
fun hasAnyChatToShareLocation() = shareChatsInfo.isNotEmpty()
|
||||||
|
|
||||||
fun isSharingLocationToChat(chatId: Long) = shareChatsInfo.contains(chatId)
|
fun isSharingLocationToChat(chatId: Long) = shareChatsInfo.containsKey(chatId)
|
||||||
|
|
||||||
fun hasAnyChatToShowOnMap() = !hiddenOnMapChats.containsAll(getLiveNowChats())
|
fun hasAnyChatToShowOnMap() = !hiddenOnMapChats.containsAll(getLiveNowChats())
|
||||||
|
|
||||||
|
@ -102,9 +109,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
hiddenChats.intersect(presentChatIds)
|
hiddenChats.intersect(presentChatIds)
|
||||||
hiddenOnMapChats = hiddenChats.toHashSet()
|
hiddenOnMapChats = hiddenChats.toHashSet()
|
||||||
|
|
||||||
shareChatsInfo = shareChatsInfo.filter { (key, _) ->
|
shareChatsInfo = ConcurrentHashMap(shareChatsInfo.filter { (key, _) -> presentChatIds.contains(key) })
|
||||||
presentChatIds.contains(key)
|
|
||||||
}.toMutableMap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareLocationToChat(
|
fun shareLocationToChat(
|
||||||
|
@ -123,14 +128,14 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
shareChatInfo = ShareChatInfo()
|
shareChatInfo = ShareChatInfo()
|
||||||
}
|
}
|
||||||
val currentTime = System.currentTimeMillis() / 1000
|
val currentTime = System.currentTimeMillis() / 1000
|
||||||
|
shareChatInfo.chatId = chatId
|
||||||
shareChatInfo.start = currentTime
|
shareChatInfo.start = currentTime
|
||||||
if (shareChatInfo.livePeriod == -1L) {
|
if (shareChatInfo.livePeriod == -1L) {
|
||||||
shareChatInfo.livePeriod = lp
|
shareChatInfo.livePeriod = lp
|
||||||
}
|
}
|
||||||
shareChatInfo.userSetLivePeriod = lp
|
shareChatInfo.userSetLivePeriod = lp
|
||||||
shareChatInfo.userSetLivePeriodStart = currentTime
|
shareChatInfo.userSetLivePeriodStart = currentTime
|
||||||
shareChatInfo.currentMessageLimit = currentTime +
|
shareChatInfo.currentMessageLimit = currentTime + Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||||
Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
|
||||||
shareChatInfo.additionalActiveTime = addActiveTime
|
shareChatInfo.additionalActiveTime = addActiveTime
|
||||||
shareChatsInfo[chatId] = shareChatInfo
|
shareChatsInfo[chatId] = shareChatInfo
|
||||||
} else {
|
} else {
|
||||||
|
@ -149,14 +154,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
fun getChatsShareInfo() = shareChatsInfo
|
fun getChatsShareInfo() = shareChatsInfo
|
||||||
|
|
||||||
fun getChatLiveMessageExpireTime(chatId: Long): Long {
|
fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1
|
||||||
val shareInfo = shareChatsInfo[chatId]
|
|
||||||
return if (shareInfo != null) {
|
|
||||||
shareInfo.userSetLivePeriod - ((System.currentTimeMillis() / 1000) - shareInfo.start)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stopSharingLocationToChats() {
|
fun stopSharingLocationToChats() {
|
||||||
shareChatsInfo.clear()
|
shareChatsInfo.clear()
|
||||||
|
@ -193,9 +191,56 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
val shareChatInfo = shareChatsInfo[message.chatId]
|
val shareChatInfo = shareChatsInfo[message.chatId]
|
||||||
val content = message.content
|
val content = message.content
|
||||||
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
||||||
|
shareChatInfo.start = message.date.toLong()
|
||||||
shareChatInfo.currentMessageId = message.id
|
shareChatInfo.currentMessageId = message.id
|
||||||
shareChatInfo.lastSuccessfulLocation = LatLon(content.location.latitude, content.location.longitude)
|
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
|
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 {
|
class DeviceBot {
|
||||||
var id: Long = -1
|
var id: Long = -1
|
||||||
var userId: Long = -1
|
var userId: Long = -1
|
||||||
|
@ -462,6 +544,30 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
var data: String = ""
|
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 {
|
class ShareChatInfo {
|
||||||
|
|
||||||
var chatId = -1L
|
var chatId = -1L
|
||||||
|
@ -472,10 +578,11 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
var userSetLivePeriod = -1L
|
var userSetLivePeriod = -1L
|
||||||
var userSetLivePeriodStart = -1L
|
var userSetLivePeriodStart = -1L
|
||||||
var lastSuccessfulLocation: LatLon? = null
|
var lastSuccessfulLocation: LatLon? = null
|
||||||
var lastSuccessfulSendTime = -1L
|
var lastSuccessfulSendTimeMs = -1L
|
||||||
var shouldDeletePreviousMessage = false
|
var shouldDeletePreviousMessage = false
|
||||||
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||||
|
var hasSharingError = false
|
||||||
|
|
||||||
fun getNextAdditionalActiveTime(): Long {
|
fun getNextAdditionalActiveTime(): Long {
|
||||||
var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime)
|
var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime)
|
||||||
return if (ADDITIONAL_ACTIVE_TIME_VALUES_SEC.lastIndex > index) {
|
return if (ADDITIONAL_ACTIVE_TIME_VALUES_SEC.lastIndex > index) {
|
||||||
|
@ -484,7 +591,11 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
ADDITIONAL_ACTIVE_TIME_VALUES_SEC[index]
|
ADDITIONAL_ACTIVE_TIME_VALUES_SEC[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getChatLiveMessageExpireTime(): Long {
|
||||||
|
return userSetLivePeriod - ((System.currentTimeMillis() / 1000) - start)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
internal const val CHAT_ID_KEY = "chatId"
|
internal const val CHAT_ID_KEY = "chatId"
|
||||||
|
|
|
@ -23,9 +23,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
|
|
||||||
var lastLocationMessageSentTime: Long = 0
|
var lastLocationMessageSentTime: Long = 0
|
||||||
|
|
||||||
private var lastTimeInMillis: Long = 0L
|
var lastLocation: Location? = null
|
||||||
|
|
||||||
private var lastLocation: Location? = null
|
|
||||||
set(value) {
|
set(value) {
|
||||||
if (lastTimeInMillis == 0L) {
|
if (lastTimeInMillis == 0L) {
|
||||||
lastTimeInMillis = System.currentTimeMillis()
|
lastTimeInMillis = System.currentTimeMillis()
|
||||||
|
@ -40,6 +38,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var lastTimeInMillis: Long = 0L
|
||||||
|
|
||||||
fun updateLocation(location: Location?) {
|
fun updateLocation(location: Location?) {
|
||||||
lastLocation = location
|
lastLocation = location
|
||||||
|
|
||||||
|
@ -54,44 +54,45 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
val url = "https://live.osmand.net/device/$sharingMode/send?lat=${location.latitude}&lon=${location.longitude}"
|
val url = "https://live.osmand.net/device/$sharingMode/send?lat=${location.latitude}&lon=${location.longitude}"
|
||||||
AndroidNetworkUtils.sendRequestAsync(url, null)
|
AndroidNetworkUtils.sendRequestAsync(url, null)
|
||||||
}
|
}
|
||||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
|
||||||
}
|
}
|
||||||
|
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
app.settings.updateSharingStatusHistory()
|
||||||
refreshNotification()
|
refreshNotification()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSendLiveMessages() {
|
fun updateSendLiveMessages() {
|
||||||
log.info("updateSendLiveMessages")
|
log.info("updateSendLiveMessages")
|
||||||
app.settings.getChatsShareInfo().forEach { chatId, shareInfo ->
|
if (app.settings.hasAnyChatToShareLocation()) {
|
||||||
val currentTime = System.currentTimeMillis() / 1000
|
app.settings.getChatsShareInfo().forEach { chatId, shareInfo ->
|
||||||
when {
|
val currentTime = System.currentTimeMillis() / 1000
|
||||||
app.settings.getChatLiveMessageExpireTime(chatId) <= 0 ->
|
when {
|
||||||
app.settings.shareLocationToChat(chatId, false)
|
shareInfo.getChatLiveMessageExpireTime() <= 0 -> app.settings.shareLocationToChat(chatId, false)
|
||||||
currentTime > shareInfo.currentMessageLimit -> {
|
currentTime > shareInfo.currentMessageLimit -> {
|
||||||
shareInfo.apply {
|
shareInfo.apply {
|
||||||
val newLivePeriod =
|
val newLivePeriod =
|
||||||
if (livePeriod > TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC) {
|
if (livePeriod > TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC) {
|
||||||
livePeriod - TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
livePeriod - TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||||
} else {
|
} else {
|
||||||
livePeriod
|
livePeriod
|
||||||
}
|
}
|
||||||
livePeriod = newLivePeriod
|
livePeriod = newLivePeriod
|
||||||
shouldDeletePreviousMessage = true
|
shouldDeletePreviousMessage = true
|
||||||
currentMessageLimit = currentTime + Math.min(
|
currentMessageLimit = currentTime + Math.min(newLivePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||||
newLivePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
}
|
||||||
}
|
}
|
||||||
}
|
shareInfo.userSetLivePeriod != shareInfo.livePeriod
|
||||||
shareInfo.userSetLivePeriod != shareInfo.livePeriod
|
&& (shareInfo.userSetLivePeriodStart + USER_SET_LIVE_PERIOD_DELAY_MS) > currentTime -> {
|
||||||
&& (shareInfo.userSetLivePeriodStart + USER_SET_LIVE_PERIOD_DELAY_MS) > currentTime -> {
|
shareInfo.apply {
|
||||||
shareInfo.apply {
|
shouldDeletePreviousMessage = true
|
||||||
shouldDeletePreviousMessage = true
|
livePeriod = shareInfo.userSetLivePeriod
|
||||||
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ class TelegramHelper private constructor() {
|
||||||
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
||||||
private const val CHATS_LIMIT = 100
|
private const val CHATS_LIMIT = 100
|
||||||
private const val IGNORED_ERROR_CODE = 406
|
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 DEVICE_PREFIX = "Device: "
|
||||||
private const val LOCATION_PREFIX = "Location: "
|
private const val LOCATION_PREFIX = "Location: "
|
||||||
|
@ -97,7 +98,6 @@ class TelegramHelper private constructor() {
|
||||||
private var haveAuthorization = false
|
private var haveAuthorization = false
|
||||||
|
|
||||||
private val defaultHandler = DefaultHandler()
|
private val defaultHandler = DefaultHandler()
|
||||||
private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
|
|
||||||
|
|
||||||
private var updateLiveMessagesExecutor: ScheduledExecutorService? = null
|
private var updateLiveMessagesExecutor: ScheduledExecutorService? = null
|
||||||
|
|
||||||
|
@ -234,7 +234,6 @@ class TelegramHelper private constructor() {
|
||||||
fun onTelegramChatChanged(chat: TdApi.Chat)
|
fun onTelegramChatChanged(chat: TdApi.Chat)
|
||||||
fun onTelegramUserChanged(user: TdApi.User)
|
fun onTelegramUserChanged(user: TdApi.User)
|
||||||
fun onTelegramError(code: Int, message: String)
|
fun onTelegramError(code: Int, message: String)
|
||||||
fun onSendLiveLocationError(code: Int, message: String)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TelegramIncomingMessagesListener {
|
interface TelegramIncomingMessagesListener {
|
||||||
|
@ -246,6 +245,7 @@ class TelegramHelper private constructor() {
|
||||||
interface TelegramOutgoingMessagesListener {
|
interface TelegramOutgoingMessagesListener {
|
||||||
fun onUpdateMessages(messages: List<TdApi.Message>)
|
fun onUpdateMessages(messages: List<TdApi.Message>)
|
||||||
fun onDeleteMessages(chatId: Long, messages: List<Long>)
|
fun onDeleteMessages(chatId: Long, messages: List<Long>)
|
||||||
|
fun onSendLiveLocationError(code: Int, message: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FullInfoUpdatesListener {
|
interface FullInfoUpdatesListener {
|
||||||
|
@ -595,19 +595,19 @@ class TelegramHelper private constructor() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopSendingLiveLocationToChat(chatId: Long, msgId: Long) {
|
fun stopSendingLiveLocationToChat(shareInfo: TelegramSettings.ShareChatInfo) {
|
||||||
if (msgId != -1L) {
|
if (shareInfo.currentMessageId != -1L && shareInfo.chatId != -1L) {
|
||||||
client?.send(
|
client?.send(
|
||||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, null),
|
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMessageId, null, null)) { obj ->
|
||||||
liveLocationMessageUpdatesHandler
|
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopSendingLiveLocationMessages(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>) {
|
fun stopSendingLiveLocationMessages(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>) {
|
||||||
chatsShareInfo.forEach { (chatId, chatInfo) ->
|
chatsShareInfo.forEach { (_, chatInfo) ->
|
||||||
stopSendingLiveLocationToChat(chatId, chatInfo.currentMessageId)
|
stopSendingLiveLocationToChat(chatInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,7 +619,9 @@ class TelegramHelper private constructor() {
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
if (error.code != IGNORED_ERROR_CODE) {
|
if (error.code != IGNORED_ERROR_CODE) {
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
listener?.onSendLiveLocationError(error.code, error.message)
|
outgoingMessagesListeners.forEach {
|
||||||
|
it.onSendLiveLocationError(error.code, error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TdApi.Messages.CONSTRUCTOR -> {
|
TdApi.Messages.CONSTRUCTOR -> {
|
||||||
|
@ -631,27 +633,29 @@ class TelegramHelper private constructor() {
|
||||||
}
|
}
|
||||||
onComplete?.invoke()
|
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
|
requestingActiveLiveLocationMessages = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recreateLiveLocationMessage(chatId: Long, msgId: Long, content: TdApi.InputMessageLocation) {
|
private fun recreateLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageLocation) {
|
||||||
if (msgId != -1L) {
|
if (shareInfo.currentMessageId != -1L && shareInfo.chatId != -1L) {
|
||||||
log.info("recreateLiveLocationMessage - $msgId")
|
log.info("recreateLiveLocationMessage - $shareInfo.currentMessageId")
|
||||||
val array = LongArray(1)
|
val array = LongArray(1)
|
||||||
array[0] = msgId
|
array[0] = shareInfo.currentMessageId
|
||||||
client?.send(TdApi.DeleteMessages(chatId, array, true)) { obj ->
|
client?.send(TdApi.DeleteMessages(shareInfo.chatId, array, true)) { obj ->
|
||||||
when (obj.constructor) {
|
when (obj.constructor) {
|
||||||
TdApi.Ok.CONSTRUCTOR -> {
|
TdApi.Ok.CONSTRUCTOR -> sendNewLiveLocationMessage(shareInfo, content)
|
||||||
sendNewLiveLocationMessage(chatId, content)
|
|
||||||
}
|
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
if (error.code != IGNORED_ERROR_CODE) {
|
if (error.code != IGNORED_ERROR_CODE) {
|
||||||
needRefreshActiveLiveLocationMessages = true
|
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
|
needRefreshActiveLiveLocationMessages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendNewLiveLocationMessage(chatId: Long, content: TdApi.InputMessageLocation) {
|
private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageLocation) {
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
log.info("sendNewLiveLocationMessage")
|
log.info("sendNewLiveLocationMessage")
|
||||||
client?.send(
|
client?.send(
|
||||||
TdApi.SendMessage(chatId, 0, false, true, null, content),
|
TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||||
liveLocationMessageUpdatesHandler
|
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendLiveLocationImpl(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, latitude: Double, longitude: Double) {
|
private fun sendLiveLocationImpl(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, latitude: Double, longitude: Double) {
|
||||||
val location = TdApi.Location(latitude, longitude)
|
val location = TdApi.Location(latitude, longitude)
|
||||||
chatsShareInfo.forEach { (chatId, shareInfo) ->
|
chatsShareInfo.forEach { (chatId, shareInfo) ->
|
||||||
|
if (shareInfo.getChatLiveMessageExpireTime() <= 0) {
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
val livePeriod =
|
val livePeriod =
|
||||||
if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
||||||
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||||
|
@ -682,18 +689,51 @@ class TelegramHelper private constructor() {
|
||||||
val msgId = shareInfo.currentMessageId
|
val msgId = shareInfo.currentMessageId
|
||||||
if (msgId != -1L) {
|
if (msgId != -1L) {
|
||||||
if (shareInfo.shouldDeletePreviousMessage) {
|
if (shareInfo.shouldDeletePreviousMessage) {
|
||||||
recreateLiveLocationMessage(chatId, msgId, content)
|
recreateLiveLocationMessage(shareInfo, content)
|
||||||
shareInfo.shouldDeletePreviousMessage = false
|
shareInfo.shouldDeletePreviousMessage = false
|
||||||
shareInfo.currentMessageId = -1
|
shareInfo.currentMessageId = -1
|
||||||
} else {
|
} else {
|
||||||
log.info("EditMessageLiveLocation - $msgId")
|
log.info("EditMessageLiveLocation - $msgId")
|
||||||
client?.send(
|
client?.send(
|
||||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, location),
|
TdApi.EditMessageLiveLocation(chatId, msgId, null, location)) { obj ->
|
||||||
liveLocationMessageUpdatesHandler
|
handleLiveLocationMessageUpdate(obj, shareInfo)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
private fun onAuthorizationStateUpdated(authorizationState: AuthorizationState?, info: Boolean = false) {
|
||||||
val prevAuthState = getTelegramAuthorizationState()
|
val prevAuthState = getTelegramAuthorizationState()
|
||||||
if (authorizationState != null) {
|
if (authorizationState != null) {
|
||||||
|
|
|
@ -170,8 +170,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
||||||
|
|
||||||
override fun onTelegramError(code: Int, message: String) {}
|
override fun onTelegramError(code: Int, message: String) {}
|
||||||
|
|
||||||
override fun onSendLiveLocationError(code: Int, message: String) {}
|
|
||||||
|
|
||||||
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
|
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
|
||||||
app.runInUIThread { updateList() }
|
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) {
|
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
|
||||||
addGrayPhoto(chatId)
|
addGrayPhoto(chatId)
|
||||||
if (!app.showLocationHelper.showingLocation && settings.hasAnyChatToShowOnMap()) {
|
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.v4.content.ContextCompat
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
@ -57,6 +59,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
private lateinit var description: TextView
|
private lateinit var description: TextView
|
||||||
private lateinit var searchBox: FrameLayout
|
private lateinit var searchBox: FrameLayout
|
||||||
private lateinit var stopSharingSwitcher: Switch
|
private lateinit var stopSharingSwitcher: Switch
|
||||||
|
private lateinit var sharingStatusDescription: TextView
|
||||||
private lateinit var startSharingBtn: View
|
private lateinit var startSharingBtn: View
|
||||||
|
|
||||||
private lateinit var searchBoxBg: GradientDrawable
|
private lateinit var searchBoxBg: GradientDrawable
|
||||||
|
@ -132,6 +135,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
AndroidUtils.addStatusBarPadding19v(context, this)
|
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 {
|
textContainer = mainView.findViewById<LinearLayout>(R.id.text_container).apply {
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
if (Build.VERSION.SDK_INT >= 16) {
|
||||||
layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
|
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)
|
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 {
|
startSharingBtn = mainView.findViewById<View>(R.id.start_sharing_btn).apply {
|
||||||
visibility = if (sharingMode) View.VISIBLE else View.GONE
|
visibility = if (sharingMode) View.VISIBLE else View.GONE
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
@ -227,6 +248,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
app.stopSharingLocation()
|
app.stopSharingLocation()
|
||||||
updateContent()
|
updateContent()
|
||||||
}
|
}
|
||||||
|
SharingStatusBottomSheet.SHARING_STATUS_REQUEST_CODE -> {
|
||||||
|
updateSharingStatus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,9 +293,6 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
override fun onTelegramError(code: Int, message: String) {
|
override fun onTelegramError(code: Int, message: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSendLiveLocationError(code: Int, message: String) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onPrimaryBtnClick() {
|
fun onPrimaryBtnClick() {
|
||||||
if (selectedChats.isNotEmpty()) {
|
if (selectedChats.isNotEmpty()) {
|
||||||
val fm = fragmentManager ?: return
|
val fm = fragmentManager ?: return
|
||||||
|
@ -394,6 +415,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateContent() {
|
private fun updateContent() {
|
||||||
|
sharingMode = sharingMode && settings.hasAnyChatToShareLocation()
|
||||||
|
updateSharingStatus()
|
||||||
updateSharingMode()
|
updateSharingMode()
|
||||||
updateList()
|
updateList()
|
||||||
}
|
}
|
||||||
|
@ -409,10 +432,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
appBarScrollRange = -1
|
appBarScrollRange = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateSharingStatus() {
|
||||||
|
if (sharingMode && settings.sharingStatusChanges.isNotEmpty()) {
|
||||||
|
sharingStatusDescription.text = settings.sharingStatusChanges.last().getDescription(app)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateList() {
|
private fun updateList() {
|
||||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||||
val currentUser = telegramHelper.getCurrentUser()
|
val currentUser = telegramHelper.getCurrentUser()
|
||||||
val chatList = if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
val chatList = if (sharingMode) {
|
||||||
settings.getShareLocationChats()
|
settings.getShareLocationChats()
|
||||||
} else {
|
} else {
|
||||||
telegramHelper.getChatListIds()
|
telegramHelper.getChatListIds()
|
||||||
|
@ -520,10 +549,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
isChecked = live
|
isChecked = live
|
||||||
setOnCheckedChangeListener { _, isChecked ->
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
val currentMessageId = shareInfo?.currentMessageId
|
|
||||||
settings.shareLocationToChat(chat.id, false)
|
settings.shareLocationToChat(chat.id, false)
|
||||||
if (currentMessageId != null) {
|
if (shareInfo != null) {
|
||||||
telegramHelper.stopSendingLiveLocationToChat(chat.id, currentMessageId)
|
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
||||||
}
|
}
|
||||||
removeItem(chat)
|
removeItem(chat)
|
||||||
}
|
}
|
||||||
|
@ -539,14 +567,15 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val expiresIn = settings.getChatLiveMessageExpireTime(chat.id)
|
val expiresIn = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||||
|
|
||||||
holder.textInArea?.apply {
|
holder.textInArea?.apply {
|
||||||
val time = shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
val time = shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = "${getText(R.string.plus)} ${OsmandFormatter.getFormattedDuration(context!!, time)}"
|
text = "${getText(R.string.plus)} ${OsmandFormatter.getFormattedDuration(context!!, time)}"
|
||||||
setOnClickListener {
|
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]
|
val nextAdditionalActiveTime = shareInfo?.getNextAdditionalActiveTime() ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[1]
|
||||||
settings.shareLocationToChat(chat.id, true, newLivePeriod, nextAdditionalActiveTime)
|
settings.shareLocationToChat(chat.id, true, newLivePeriod, nextAdditionalActiveTime)
|
||||||
notifyItemChanged(position)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ object OsmandFormatter {
|
||||||
val FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f
|
val FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f
|
||||||
private val fixed2 = DecimalFormat("0.00")
|
private val fixed2 = DecimalFormat("0.00")
|
||||||
private val fixed1 = DecimalFormat("0.0")
|
private val fixed1 = DecimalFormat("0.0")
|
||||||
|
|
||||||
private const val SHORT_TIME_FORMAT = "%02d:%02d"
|
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"
|
||||||
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
||||||
|
@ -62,9 +62,13 @@ object OsmandFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFormattedTime(seconds: Long): String {
|
fun getFormattedTime(milliseconds: Long, useCurrentTime: Boolean = true): String {
|
||||||
val calendar = Calendar.getInstance()
|
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())) {
|
return if (isSameDay(calendar, Calendar.getInstance())) {
|
||||||
SimpleDateFormat(SIMPLE_TIME_OF_DAY_FORMAT, Locale.getDefault()).format(calendar.time)
|
SimpleDateFormat(SIMPLE_TIME_OF_DAY_FORMAT, Locale.getDefault()).format(calendar.time)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -107,6 +107,10 @@ class UiUtils(private val app: TelegramApplication) {
|
||||||
return getDrawable(id, if (isLightContent) R.color.ctrl_active_light else 0)
|
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? {
|
fun getIcon(@DrawableRes id: Int): Drawable? {
|
||||||
return getDrawable(id, 0)
|
return getDrawable(id, 0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue