diff --git a/OsmAnd-telegram/res/drawable-hdpi/img_google_play_badge.png b/OsmAnd-telegram/res/drawable-hdpi/img_google_play_badge.png new file mode 100644 index 0000000000..c0f1afabb4 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-hdpi/img_google_play_badge.png differ diff --git a/OsmAnd-telegram/res/drawable-hdpi/img_group_picture.png b/OsmAnd-telegram/res/drawable-hdpi/img_group_picture.png new file mode 100644 index 0000000000..f1b64b5f2f Binary files /dev/null and b/OsmAnd-telegram/res/drawable-hdpi/img_group_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-hdpi/img_user_picture.png b/OsmAnd-telegram/res/drawable-hdpi/img_user_picture.png index 9d021bc40a..155805c7c5 100644 Binary files a/OsmAnd-telegram/res/drawable-hdpi/img_user_picture.png and b/OsmAnd-telegram/res/drawable-hdpi/img_user_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/img_google_play_badge.png b/OsmAnd-telegram/res/drawable-mdpi/img_google_play_badge.png new file mode 100644 index 0000000000..3c970ebbf3 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-mdpi/img_google_play_badge.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/img_group_picture.png b/OsmAnd-telegram/res/drawable-mdpi/img_group_picture.png new file mode 100644 index 0000000000..622720cb35 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-mdpi/img_group_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/img_user_picture.png b/OsmAnd-telegram/res/drawable-mdpi/img_user_picture.png index f88b2c317e..5a5f81bd69 100644 Binary files a/OsmAnd-telegram/res/drawable-mdpi/img_user_picture.png and b/OsmAnd-telegram/res/drawable-mdpi/img_user_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/img_google_play_badge.png b/OsmAnd-telegram/res/drawable-xhdpi/img_google_play_badge.png new file mode 100644 index 0000000000..c6f34ed2ae Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xhdpi/img_google_play_badge.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/img_group_picture.png b/OsmAnd-telegram/res/drawable-xhdpi/img_group_picture.png new file mode 100644 index 0000000000..bab5e622d4 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xhdpi/img_group_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/img_user_picture.png b/OsmAnd-telegram/res/drawable-xhdpi/img_user_picture.png index 83fc3d566a..0ef799e12a 100644 Binary files a/OsmAnd-telegram/res/drawable-xhdpi/img_user_picture.png and b/OsmAnd-telegram/res/drawable-xhdpi/img_user_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/img_google_play_badge.png b/OsmAnd-telegram/res/drawable-xxhdpi/img_google_play_badge.png new file mode 100644 index 0000000000..3cb5ba461a Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxhdpi/img_google_play_badge.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/img_group_picture.png b/OsmAnd-telegram/res/drawable-xxhdpi/img_group_picture.png new file mode 100644 index 0000000000..48adb67275 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxhdpi/img_group_picture.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/img_user_picture.png b/OsmAnd-telegram/res/drawable-xxhdpi/img_user_picture.png index 5121466ae7..6bbbe923eb 100644 Binary files a/OsmAnd-telegram/res/drawable-xxhdpi/img_user_picture.png and b/OsmAnd-telegram/res/drawable-xxhdpi/img_user_picture.png differ diff --git a/OsmAnd-telegram/res/layout/chat_list_item.xml b/OsmAnd-telegram/res/layout/chat_list_item.xml index dbeb1ebc5c..fefedd3125 100644 --- a/OsmAnd-telegram/res/layout/chat_list_item.xml +++ b/OsmAnd-telegram/res/layout/chat_list_item.xml @@ -22,7 +22,7 @@ android:layout_width="40dp" android:layout_height="40dp" android:scaleType="centerInside" - android:src="@drawable/ic_group" + android:src="@drawable/img_group_picture" android:visibility="visible" /> - + + + + + + + + + + + + + + + diff --git a/OsmAnd-telegram/res/layout/user_list_item.xml b/OsmAnd-telegram/res/layout/user_list_item.xml index e93f481f16..9f362b6603 100644 --- a/OsmAnd-telegram/res/layout/user_list_item.xml +++ b/OsmAnd-telegram/res/layout/user_list_item.xml @@ -48,16 +48,61 @@ app:typeface="@string/font_roboto_regular" tools:text="Share location"/> - + + + + + + + + + + + + + + + diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index 48664f5882..ffb7f37ae7 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -247,6 +247,10 @@ class TelegramHelper private constructor() { } } + fun isOsmAndBot(userId: Int) = users[userId]?.username == OSMAND_BOT_USERNAME + + fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot + fun startLiveMessagesUpdates() { stopLiveMessagesUpdates() @@ -612,7 +616,7 @@ class TelegramHelper private constructor() { is TdApi.MessageText -> { if (content.text.text.startsWith("{")) { // TODO: get user from library if null - if (users[senderUserId]?.username == OSMAND_BOT_USERNAME) { + if (isOsmAndBot(senderUserId)) { return true } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt index ed9126d182..848e5d0c64 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt @@ -34,6 +34,27 @@ object TelegramUiHelper { } } + fun chatToChatItem( + helper: TelegramHelper, + chat: TdApi.Chat, + messages: List + ): ChatItem { + val res = ChatItem().apply { + title = chat.title + photoPath = chat.photo?.small?.local?.path + placeholderId = R.drawable.ic_group + } + val chatType = chat.type + if (chatType is TdApi.ChatTypePrivate && !helper.isBot(chatType.userId)) { + val content = messages.firstOrNull()?.content + if (content is TdApi.MessageLocation) { + res.lat = content.location.latitude + res.lon = content.location.longitude + } + } + return res + } + fun messageToLocationItem(helper: TelegramHelper, message: TdApi.Message): LocationItem? { val content = message.content return when (content) { @@ -77,6 +98,19 @@ object TelegramUiHelper { } } + class ChatItem { + var title: String = "" + internal set + var lat: Double = 0.0 + internal set + var lon: Double = 0.0 + internal set + var photoPath: String? = null + internal set + var placeholderId: Int = 0 + internal set + } + class LocationItem { var name: String = "" internal set diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt index d30752baac..ce254b0a3d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/LiveNowTabFragment.kt @@ -16,13 +16,14 @@ import android.widget.TextView import net.osmand.Location import net.osmand.telegram.R import net.osmand.telegram.TelegramApplication +import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener -import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.helpers.TelegramHelper.* import net.osmand.telegram.helpers.TelegramUiHelper +import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem import net.osmand.telegram.helpers.TelegramUiHelper.LocationItem import net.osmand.telegram.utils.AndroidUtils -import net.osmand.telegram.utils.OsmandFormatter +import net.osmand.telegram.utils.UiUtils.UpdateLocationViewCache import net.osmand.util.MapUtils import org.drinkless.td.libcore.telegram.TdApi @@ -30,7 +31,7 @@ private const val CHAT_VIEW_TYPE = 0 private const val LOCATION_ITEM_VIEW_TYPE = 1 class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessagesListener, - TelegramLocationListener { + TelegramLocationListener, TelegramCompassListener { private val app: TelegramApplication get() = activity?.application as TelegramApplication @@ -40,8 +41,11 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage private val settings get() = app.settings private lateinit var adapter: LiveNowListAdapter + private lateinit var locationViewCache: UpdateLocationViewCache private var location: Location? = null + private var heading: Float? = null + private var locationUiUpdateAllowed: Boolean = true override fun onCreateView( inflater: LayoutInflater, @@ -53,12 +57,19 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage mainView.findViewById(R.id.recycler_view).apply { layoutManager = LinearLayoutManager(context) adapter = this@LiveNowTabFragment.adapter + addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + locationUiUpdateAllowed = newState == RecyclerView.SCROLL_STATE_IDLE + } + }) } return mainView } override fun onResume() { super.onResume() + locationViewCache = app.uiUtils.getUpdateLocationViewCache() updateList() telegramHelper.addIncomingMessagesListener(this) startLocationUpdate() @@ -124,24 +135,40 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage } } + override fun updateCompassValue(value: Float) { + // 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction) + // on non-compass devices + val lastHeading = heading ?: 99f + heading = value + if (Math.abs(MapUtils.degreesDiff(lastHeading.toDouble(), value.toDouble())) > 5) { + updateLocationUi() + } else { + heading = lastHeading + } + } + fun startLocationUpdate() { app.locationProvider.addLocationListener(this) + app.locationProvider.addCompassListener(this) updateLocationUi() } fun stopLocationUpdate() { app.locationProvider.removeLocationListener(this) + app.locationProvider.removeCompassListener(this) } private fun updateLocationUi() { - adapter.notifyDataSetChanged() + if (locationUiUpdateAllowed) { + app.runInUIThread { adapter.notifyDataSetChanged() } + } } private fun updateList() { val res = mutableListOf() for ((id, messages) in telegramHelper.getMessagesByChatIds()) { telegramHelper.getChat(id)?.also { chat -> - res.add(chat) + res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages)) if (needLocationItems(chat.type)) { res.addAll(convertToLocationItems(messages)) } @@ -154,9 +181,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage return when (type) { is TdApi.ChatTypeBasicGroup -> true is TdApi.ChatTypeSupergroup -> true - is TdApi.ChatTypePrivate -> { - telegramHelper.getUser(type.userId)?.username == TelegramHelper.OSMAND_BOT_USERNAME - } + is TdApi.ChatTypePrivate -> telegramHelper.isOsmAndBot(type.userId) else -> false } } @@ -202,31 +227,49 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val lastItem = position == itemCount - 1 val item = items[position] - if (item is TdApi.Chat && holder is ChatViewHolder) { - val nextItemIsUser = !lastItem && items[position + 1] is TdApi.User + if (item is ChatItem && holder is ChatViewHolder) { + val nextIsLocation = !lastItem && items[position + 1] is LocationItem val chatTitle = item.title val stateTextInd = if (settings.isShowingChatOnMap(chatTitle)) 1 else 0 - TelegramUiHelper.setupPhoto(app, holder.icon, item.photo?.small?.local?.path) + TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId) holder.title?.text = chatTitle + if (location != null) { + holder.locationViewContainer?.visibility = View.VISIBLE + // TODO: locationViewCache.outdatedLocation + app.uiUtils.updateLocationView( + holder.directionIcon, + holder.distanceText, + location!!.latitude, + location!!.longitude, + locationViewCache + ) + } else { + holder.locationViewContainer?.visibility = View.GONE + } holder.description?.text = "Chat description" // FIXME holder.imageButton?.visibility = View.GONE holder.showOnMapRow?.setOnClickListener { showPopupMenu(holder, chatTitle) } holder.showOnMapState?.text = menuList[stateTextInd] - holder.bottomDivider?.visibility = if (nextItemIsUser) View.VISIBLE else View.GONE + holder.bottomDivider?.visibility = if (nextIsLocation) View.VISIBLE else View.GONE holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE } else if (item is LocationItem && holder is ContactViewHolder) { TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId) holder.title?.text = item.name if (location != null) { - val dist = MapUtils.getDistance( - location!!.latitude, location!!.longitude, - item.lat, item.lon - ).toFloat() - holder.description?.text = OsmandFormatter.getFormattedDistance(dist, app) + holder.locationViewContainer?.visibility = View.VISIBLE + // TODO: locationViewCache.outdatedLocation + app.uiUtils.updateLocationView( + holder.directionIcon, + holder.distanceText, + location!!.latitude, + location!!.longitude, + locationViewCache + ) } else { - holder.description?.text = "Current location is not available" + holder.locationViewContainer?.visibility = View.GONE } + holder.description?.text = "Some description" holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE } } @@ -286,6 +329,9 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage inner class ContactViewHolder(val view: View) : RecyclerView.ViewHolder(view) { val icon: ImageView? = view.findViewById(R.id.icon) val title: TextView? = view.findViewById(R.id.title) + val locationViewContainer: View? = view.findViewById(R.id.location_view_container) + val directionIcon: ImageView? = view.findViewById(R.id.direction_icon) + val distanceText: TextView? = view.findViewById(R.id.distance_text) val description: TextView? = view.findViewById(R.id.description) val bottomShadow: View? = view.findViewById(R.id.bottom_shadow) } @@ -293,6 +339,9 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) { val icon: ImageView? = view.findViewById(R.id.icon) val title: TextView? = view.findViewById(R.id.title) + val locationViewContainer: View? = view.findViewById(R.id.location_view_container) + val directionIcon: ImageView? = view.findViewById(R.id.direction_icon) + val distanceText: TextView? = view.findViewById(R.id.distance_text) val description: TextView? = view.findViewById(R.id.description) val imageButton: ImageView? = view.findViewById(R.id.image_button) val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt index cf99430efe..700cf1e100 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt @@ -58,6 +58,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene private val listeners: MutableList> = mutableListOf() private var myLocationTabFragment: MyLocationTabFragment? = null + private var liveNowTabFragment: LiveNowTabFragment? = null private lateinit var buttonsBar: LinearLayout private lateinit var bottomNav: BottomNavigationView @@ -82,6 +83,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene R.id.action_live_now -> pos = LIVE_NOW_TAB_POS } if (pos != -1 && pos != viewPager.currentItem) { + when (pos) { + MY_LOCATION_TAB_POS -> liveNowTabFragment?.stopLocationUpdate() + LIVE_NOW_TAB_POS -> liveNowTabFragment?.startLocationUpdate() + } viewPager.currentItem = pos return@setOnNavigationItemSelectedListener true } @@ -137,6 +142,8 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene } if (fragment is MyLocationTabFragment) { myLocationTabFragment = fragment + } else if (fragment is LiveNowTabFragment) { + liveNowTabFragment = fragment } }