Merge branch 'master' of ssh://github.com/osmandapp/Osmand into LoginDialogsUiImprovements

This commit is contained in:
Chumva 2018-07-06 17:37:27 +03:00
commit aded984134
19 changed files with 224 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -22,7 +22,7 @@
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:scaleType="centerInside" android:scaleType="centerInside"
android:src="@drawable/ic_group" android:src="@drawable/img_group_picture"
android:visibility="visible" /> android:visibility="visible" />
<android.support.v7.widget.AppCompatTextView <android.support.v7.widget.AppCompatTextView

View file

@ -49,16 +49,61 @@
app:typeface="@string/font_roboto_regular" app:typeface="@string/font_roboto_regular"
tools:text="Share location"/> tools:text="Share location"/>
<net.osmand.telegram.ui.views.TextViewEx <LinearLayout
android:id="@+id/description" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:ellipsize="end" <LinearLayout
android:maxLines="1" android:id="@+id/location_view_container"
android:textColor="?attr/android:textColorSecondary" android:layout_width="wrap_content"
android:textSize="@dimen/list_item_description_text_size" android:layout_height="wrap_content"
app:typeface="@string/font_roboto_regular" android:gravity="center_vertical"
tools:text="Live: 1 • All: 36"/> android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
tools:src="@drawable/ic_direction_arrow"
tools:tint="@color/ctrl_active_light"/>
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/distance_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="@dimen/list_item_description_text_size"
app:typeface="@string/font_roboto_medium"
tools:text="213 m"
tools:textColor="@color/ctrl_active_light"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:text="•"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"/>
</LinearLayout>
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:typeface="@string/font_roboto_regular"
tools:text="Live: 1 • All: 36"/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -48,16 +48,61 @@
app:typeface="@string/font_roboto_regular" app:typeface="@string/font_roboto_regular"
tools:text="Share location"/> tools:text="Share location"/>
<net.osmand.telegram.ui.views.TextViewEx <LinearLayout
android:id="@+id/description" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:ellipsize="end" <LinearLayout
android:maxLines="1" android:id="@+id/location_view_container"
android:textColor="?attr/android:textColorSecondary" android:layout_width="wrap_content"
android:textSize="@dimen/list_item_description_text_size" android:layout_height="wrap_content"
app:typeface="@string/font_roboto_regular" android:gravity="center_vertical"
tools:text="Live: 1 • All: 36"/> android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
tools:src="@drawable/ic_direction_arrow"
tools:tint="@color/ctrl_active_light"/>
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/distance_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="@dimen/list_item_description_text_size"
app:typeface="@string/font_roboto_medium"
tools:text="213 m"
tools:textColor="@color/ctrl_active_light"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:text="•"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"/>
</LinearLayout>
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:typeface="@string/font_roboto_regular"
tools:text="Live: 1 • All: 36"/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -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() { fun startLiveMessagesUpdates() {
stopLiveMessagesUpdates() stopLiveMessagesUpdates()
@ -612,7 +616,7 @@ class TelegramHelper private constructor() {
is TdApi.MessageText -> { is TdApi.MessageText -> {
if (content.text.text.startsWith("{")) { if (content.text.text.startsWith("{")) {
// TODO: get user from library if null // TODO: get user from library if null
if (users[senderUserId]?.username == OSMAND_BOT_USERNAME) { if (isOsmAndBot(senderUserId)) {
return true return true
} }
} }

View file

@ -34,6 +34,27 @@ object TelegramUiHelper {
} }
} }
fun chatToChatItem(
helper: TelegramHelper,
chat: TdApi.Chat,
messages: List<TdApi.Message>
): 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? { fun messageToLocationItem(helper: TelegramHelper, message: TdApi.Message): LocationItem? {
val content = message.content val content = message.content
return when (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 { class LocationItem {
var name: String = "" var name: String = ""
internal set internal set

View file

@ -16,13 +16,14 @@ import android.widget.TextView
import net.osmand.Location import net.osmand.Location
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.helpers.TelegramHelper.* import net.osmand.telegram.helpers.TelegramHelper.*
import net.osmand.telegram.helpers.TelegramUiHelper import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
import net.osmand.telegram.helpers.TelegramUiHelper.LocationItem import net.osmand.telegram.helpers.TelegramUiHelper.LocationItem
import net.osmand.telegram.utils.AndroidUtils 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 net.osmand.util.MapUtils
import org.drinkless.td.libcore.telegram.TdApi 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 private const val LOCATION_ITEM_VIEW_TYPE = 1
class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessagesListener, class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessagesListener,
TelegramLocationListener { TelegramLocationListener, TelegramCompassListener {
private val app: TelegramApplication private val app: TelegramApplication
get() = activity?.application as TelegramApplication get() = activity?.application as TelegramApplication
@ -40,8 +41,11 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
private val settings get() = app.settings private val settings get() = app.settings
private lateinit var adapter: LiveNowListAdapter private lateinit var adapter: LiveNowListAdapter
private lateinit var locationViewCache: UpdateLocationViewCache
private var location: Location? = null private var location: Location? = null
private var heading: Float? = null
private var locationUiUpdateAllowed: Boolean = true
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -53,12 +57,19 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
mainView.findViewById<RecyclerView>(R.id.recycler_view).apply { mainView.findViewById<RecyclerView>(R.id.recycler_view).apply {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = this@LiveNowTabFragment.adapter 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 return mainView
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
locationViewCache = app.uiUtils.getUpdateLocationViewCache()
updateList() updateList()
telegramHelper.addIncomingMessagesListener(this) telegramHelper.addIncomingMessagesListener(this)
startLocationUpdate() 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() { fun startLocationUpdate() {
app.locationProvider.addLocationListener(this) app.locationProvider.addLocationListener(this)
app.locationProvider.addCompassListener(this)
updateLocationUi() updateLocationUi()
} }
fun stopLocationUpdate() { fun stopLocationUpdate() {
app.locationProvider.removeLocationListener(this) app.locationProvider.removeLocationListener(this)
app.locationProvider.removeCompassListener(this)
} }
private fun updateLocationUi() { private fun updateLocationUi() {
adapter.notifyDataSetChanged() if (locationUiUpdateAllowed) {
app.runInUIThread { adapter.notifyDataSetChanged() }
}
} }
private fun updateList() { private fun updateList() {
val res = mutableListOf<Any>() val res = mutableListOf<Any>()
for ((id, messages) in telegramHelper.getMessagesByChatIds()) { for ((id, messages) in telegramHelper.getMessagesByChatIds()) {
telegramHelper.getChat(id)?.also { chat -> telegramHelper.getChat(id)?.also { chat ->
res.add(chat) res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages))
if (needLocationItems(chat.type)) { if (needLocationItems(chat.type)) {
res.addAll(convertToLocationItems(messages)) res.addAll(convertToLocationItems(messages))
} }
@ -154,9 +181,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
return when (type) { return when (type) {
is TdApi.ChatTypeBasicGroup -> true is TdApi.ChatTypeBasicGroup -> true
is TdApi.ChatTypeSupergroup -> true is TdApi.ChatTypeSupergroup -> true
is TdApi.ChatTypePrivate -> { is TdApi.ChatTypePrivate -> telegramHelper.isOsmAndBot(type.userId)
telegramHelper.getUser(type.userId)?.username == TelegramHelper.OSMAND_BOT_USERNAME
}
else -> false else -> false
} }
} }
@ -202,31 +227,49 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val lastItem = position == itemCount - 1 val lastItem = position == itemCount - 1
val item = items[position] val item = items[position]
if (item is TdApi.Chat && holder is ChatViewHolder) { if (item is ChatItem && holder is ChatViewHolder) {
val nextItemIsUser = !lastItem && items[position + 1] is TdApi.User val nextIsLocation = !lastItem && items[position + 1] is LocationItem
val chatTitle = item.title val chatTitle = item.title
val stateTextInd = if (settings.isShowingChatOnMap(chatTitle)) 1 else 0 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 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.description?.text = "Chat description" // FIXME
holder.imageButton?.visibility = View.GONE holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.setOnClickListener { showPopupMenu(holder, chatTitle) } holder.showOnMapRow?.setOnClickListener { showPopupMenu(holder, chatTitle) }
holder.showOnMapState?.text = menuList[stateTextInd] 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 holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
} else if (item is LocationItem && holder is ContactViewHolder) { } else if (item is LocationItem && holder is ContactViewHolder) {
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId) TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId)
holder.title?.text = item.name holder.title?.text = item.name
if (location != null) { if (location != null) {
val dist = MapUtils.getDistance( holder.locationViewContainer?.visibility = View.VISIBLE
location!!.latitude, location!!.longitude, // TODO: locationViewCache.outdatedLocation
item.lat, item.lon app.uiUtils.updateLocationView(
).toFloat() holder.directionIcon,
holder.description?.text = OsmandFormatter.getFormattedDistance(dist, app) holder.distanceText,
location!!.latitude,
location!!.longitude,
locationViewCache
)
} else { } 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 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) { inner class ContactViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView? = view.findViewById(R.id.icon) val icon: ImageView? = view.findViewById(R.id.icon)
val title: TextView? = view.findViewById(R.id.title) 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 description: TextView? = view.findViewById(R.id.description)
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow) 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) { inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView? = view.findViewById(R.id.icon) val icon: ImageView? = view.findViewById(R.id.icon)
val title: TextView? = view.findViewById(R.id.title) 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 description: TextView? = view.findViewById(R.id.description)
val imageButton: ImageView? = view.findViewById(R.id.image_button) val imageButton: ImageView? = view.findViewById(R.id.image_button)
val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row) val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row)

View file

@ -58,6 +58,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
private val listeners: MutableList<WeakReference<TelegramListener>> = mutableListOf() private val listeners: MutableList<WeakReference<TelegramListener>> = mutableListOf()
private var myLocationTabFragment: MyLocationTabFragment? = null private var myLocationTabFragment: MyLocationTabFragment? = null
private var liveNowTabFragment: LiveNowTabFragment? = null
private lateinit var buttonsBar: LinearLayout private lateinit var buttonsBar: LinearLayout
private lateinit var bottomNav: BottomNavigationView private lateinit var bottomNav: BottomNavigationView
@ -82,6 +83,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
R.id.action_live_now -> pos = LIVE_NOW_TAB_POS R.id.action_live_now -> pos = LIVE_NOW_TAB_POS
} }
if (pos != -1 && pos != viewPager.currentItem) { if (pos != -1 && pos != viewPager.currentItem) {
when (pos) {
MY_LOCATION_TAB_POS -> liveNowTabFragment?.stopLocationUpdate()
LIVE_NOW_TAB_POS -> liveNowTabFragment?.startLocationUpdate()
}
viewPager.currentItem = pos viewPager.currentItem = pos
return@setOnNavigationItemSelectedListener true return@setOnNavigationItemSelectedListener true
} }
@ -137,6 +142,8 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
} }
if (fragment is MyLocationTabFragment) { if (fragment is MyLocationTabFragment) {
myLocationTabFragment = fragment myLocationTabFragment = fragment
} else if (fragment is LiveNowTabFragment) {
liveNowTabFragment = fragment
} }
} }