Telegram sharing status init
This commit is contained in:
parent
519827262c
commit
0ff05fd0a6
15 changed files with 595 additions and 74 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>
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout
|
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -16,6 +15,7 @@
|
||||||
android:id="@+id/image_container"
|
android:id="@+id/image_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/my_location_image_height"
|
android:layout_height="@dimen/my_location_image_height"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_scrollFlags="scroll">
|
app:layout_scrollFlags="scroll">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -50,11 +50,12 @@
|
||||||
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">
|
android:visibility="gone">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -157,6 +158,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,23 +168,21 @@
|
||||||
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"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -192,14 +192,21 @@
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||||
android:layout_marginStart="@dimen/content_padding_standard"
|
android:layout_marginStart="@dimen/content_padding_standard"
|
||||||
android:background="?attr/card_divider_color" />
|
android:background="?attr/card_divider_color"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
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: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:background="?attr/selectableItemBackground"
|
||||||
android:gravity="center_vertical"
|
android:orientation="horizontal"
|
||||||
android:paddingLeft="@dimen/content_padding_standard"
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
android:paddingRight="@dimen/content_padding_standard">
|
android:paddingRight="@dimen/content_padding_standard">
|
||||||
|
|
||||||
|
@ -207,35 +214,96 @@
|
||||||
android:id="@+id/stop_all_sharing_title"
|
android:id="@+id/stop_all_sharing_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||||
android:layout_marginRight="@dimen/content_padding_standard"
|
android:layout_marginRight="@dimen/content_padding_standard"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="@string/stop_sharing_all"
|
android:text="@string/shared_string_disable"
|
||||||
android:textColor="?attr/ctrl_active_color"
|
android:textColor="?attr/ctrl_active_color"
|
||||||
android:textSize="@dimen/descr_text_size"
|
android:textSize="@dimen/hint_text_size"
|
||||||
app:typeface="@string/font_roboto_medium" />
|
app:lastBaselineToBottomHeight="24dp"
|
||||||
|
app:typeface="@string/font_roboto_medium"/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/stop_all_sharing_switcher"
|
android:id="@+id/stop_all_sharing_switcher"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:focusable="false"/>
|
android:focusable="false"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</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"
|
||||||
|
android:src="@drawable/ic_action_live_now"
|
||||||
|
android: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>
|
</LinearLayout>
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:layout_height="match_parent">
|
tools:visibility="gone">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
|
@ -258,8 +326,8 @@
|
||||||
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"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
106
OsmAnd-telegram/res/layout/item_with_four_text_lines.xml
Normal file
106
OsmAnd-telegram/res/layout/item_with_four_text_lines.xml
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<?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">
|
||||||
|
|
||||||
|
<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: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>
|
||||||
|
|
||||||
|
<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:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
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:background="?attr/card_divider_color"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
|
|
@ -45,6 +45,9 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
|
||||||
var lastKnownLocation: net.osmand.Location? = null
|
var lastKnownLocation: net.osmand.Location? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var lastKnownLocationTime: Long? = null
|
||||||
|
private set
|
||||||
|
|
||||||
val gpsInfo = GPSInfo()
|
val gpsInfo = GPSInfo()
|
||||||
|
|
||||||
private val locationListeners = ArrayList<TelegramLocationListener>()
|
private val locationListeners = ArrayList<TelegramLocationListener>()
|
||||||
|
@ -432,6 +435,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
|
||||||
updateGPSInfo(null)
|
updateGPSInfo(null)
|
||||||
}
|
}
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
|
lastKnownLocationTime = location.time
|
||||||
if (gpsSignalLost) {
|
if (gpsSignalLost) {
|
||||||
gpsSignalLost = false
|
gpsSignalLost = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
||||||
updateShareInfoHandler?.postDelayed({
|
updateShareInfoHandler?.postDelayed({
|
||||||
if (isUsedByMyLocation(usedBy)) {
|
if (isUsedByMyLocation(usedBy)) {
|
||||||
app().shareLocationHelper.updateSendLiveMessages()
|
app().shareLocationHelper.updateSendLiveMessages()
|
||||||
|
app().settings.updateSharingStatusHistory()
|
||||||
startShareInfoUpdates()
|
startShareInfoUpdates()
|
||||||
}
|
}
|
||||||
}, UPDATE_LIVE_MESSAGES_INTERVAL_MS)
|
}, UPDATE_LIVE_MESSAGES_INTERVAL_MS)
|
||||||
|
@ -296,6 +297,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,9 @@ 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,6 +130,7 @@ 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
|
||||||
|
@ -149,6 +157,8 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
fun getChatsShareInfo() = shareChatsInfo
|
fun getChatsShareInfo() = shareChatsInfo
|
||||||
|
|
||||||
|
fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1
|
||||||
|
|
||||||
fun getChatLiveMessageExpireTime(chatId: Long): Long {
|
fun getChatLiveMessageExpireTime(chatId: Long): Long {
|
||||||
val shareInfo = shareChatsInfo[chatId]
|
val shareInfo = shareChatsInfo[chatId]
|
||||||
return if (shareInfo != null) {
|
return if (shareInfo != null) {
|
||||||
|
@ -195,7 +205,56 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
||||||
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) {
|
||||||
|
SharingStatusType.NO_INTERNET
|
||||||
|
} else if (app.locationProvider.lastKnownLocation == null || !app.locationProvider.gpsInfo.fixed) {
|
||||||
|
SharingStatusType.NO_GPS
|
||||||
|
} else {
|
||||||
|
var sendChatErrors = false
|
||||||
|
shareChatsInfo.forEach { _, shareInfo ->
|
||||||
|
if ((statusChangeTime - shareInfo.lastSuccessfulSendTimeMs) > (sendMyLocInterval * 2) * 1000) {
|
||||||
|
sendChatErrors = true
|
||||||
|
locationTime = shareInfo.lastSuccessfulSendTimeMs
|
||||||
|
val title = app.telegramHelper.getChat(shareInfo.chatId)?.title
|
||||||
|
if (title != null) {
|
||||||
|
chatsTitles.add(title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sendChatErrors) {
|
||||||
|
SharingStatusType.NOT_POSSIBLE_TO_SENT_TO_CHATS
|
||||||
|
} else {
|
||||||
|
SharingStatusType.SUCCESSFULLY_SENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (statusType == SharingStatusType.NO_INTERNET || statusType == SharingStatusType.SUCCESSFULLY_SENT) {
|
||||||
|
locationTime = getLastSuccessfulSendTime()
|
||||||
|
} else if (statusType == SharingStatusType.NO_GPS) {
|
||||||
|
locationTime = app.locationProvider.lastKnownLocationTime ?: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sharingStatusChanges.isNotEmpty()) {
|
||||||
|
val lastSharingStatus = sharingStatusChanges.last()
|
||||||
|
if (lastSharingStatus.statusType != newSharingStatus.statusType) {
|
||||||
|
sharingStatusChanges.add(newSharingStatus)
|
||||||
|
} else {
|
||||||
|
lastSharingStatus.apply {
|
||||||
|
statusChangeTime = newSharingStatus.statusChangeTime
|
||||||
|
locationTime = newSharingStatus.locationTime
|
||||||
|
chatsTitles = newSharingStatus.chatsTitles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sharingStatusChanges.add(newSharingStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,6 +512,43 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
fun isSortByGroup() = this == SORT_BY_GROUP
|
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 +558,35 @@ 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,7 +597,7 @@ 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]
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -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,7 +633,9 @@ 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
|
||||||
}
|
}
|
||||||
|
@ -651,7 +655,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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,14 +764,18 @@ 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.Message.CONSTRUCTOR -> {
|
TdApi.Message.CONSTRUCTOR -> {
|
||||||
if (obj is TdApi.Message) {
|
if (obj is TdApi.Message) {
|
||||||
if (obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
|
if (obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
listener?.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send")
|
outgoingMessagesListeners.forEach {
|
||||||
|
it.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
outgoingMessagesListeners.forEach {
|
outgoingMessagesListeners.forEach {
|
||||||
it.onUpdateMessages(listOf(obj))
|
it.onUpdateMessages(listOf(obj))
|
||||||
|
|
|
@ -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,14 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
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 +192,17 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainView.findViewById<View>(R.id.sharing_status_container).setOnClickListener {
|
||||||
|
settings.updateSharingStatusHistory()
|
||||||
|
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 {
|
||||||
|
@ -269,9 +289,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 +411,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateContent() {
|
private fun updateContent() {
|
||||||
|
updateSharingStatus()
|
||||||
updateSharingMode()
|
updateSharingMode()
|
||||||
updateList()
|
updateList()
|
||||||
}
|
}
|
||||||
|
@ -409,6 +427,15 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
appBarScrollRange = -1
|
appBarScrollRange = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateSharingStatus() {
|
||||||
|
if (sharingMode) {
|
||||||
|
if (settings.sharingStatusChanges.isEmpty()) {
|
||||||
|
settings.updateSharingStatusHistory()
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package net.osmand.telegram.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.design.widget.BottomSheetBehavior
|
||||||
|
import android.support.v4.app.DialogFragment
|
||||||
|
import android.support.v4.app.Fragment
|
||||||
|
import android.support.v4.app.FragmentManager
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import net.osmand.telegram.R
|
||||||
|
import net.osmand.telegram.TelegramApplication
|
||||||
|
import net.osmand.telegram.TelegramSettings
|
||||||
|
import net.osmand.telegram.ui.views.BottomSheetDialog
|
||||||
|
import net.osmand.telegram.utils.OsmandFormatter
|
||||||
|
|
||||||
|
class SharingStatusBottomSheet : DialogFragment() {
|
||||||
|
private val app: TelegramApplication
|
||||||
|
get() = activity?.application as TelegramApplication
|
||||||
|
private val settings get() = app.settings
|
||||||
|
private val uiUtils get() = app.uiUtils
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(context!!)
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
val mainView = inflater.inflate(R.layout.bottom_sheet_sharing_status, container, false)
|
||||||
|
mainView.findViewById<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) {
|
||||||
|
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_four_text_lines, itemsCont, false).apply {
|
||||||
|
val sharingStatusType = sharingStatus.statusType
|
||||||
|
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)
|
||||||
|
val time = sharingStatus.locationTime
|
||||||
|
findViewById<TextView>(R.id.last_location_line).text = getString(sharingStatusType.descriptionId)
|
||||||
|
if (time > 0) {
|
||||||
|
val sentTime = OsmandFormatter.getFormattedTime(time, false)
|
||||||
|
findViewById<TextView>(R.id.last_location_line_time).text = sentTime
|
||||||
|
} else {
|
||||||
|
findViewById<TextView>(R.id.last_location_line_time).text = "-"
|
||||||
|
}
|
||||||
|
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 { 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ object OsmandFormatter {
|
||||||
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:ss"
|
||||||
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
||||||
|
|
||||||
private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60
|
private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60
|
||||||
|
@ -62,9 +62,13 @@ object OsmandFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFormattedTime(seconds: Long): String {
|
fun getFormattedTime(milliseconds: Long, useCurrentTime: Boolean = true): String {
|
||||||
val calendar = Calendar.getInstance()
|
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