/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.fenix.home.sessioncontrol.viewholders import android.graphics.Color import android.graphics.LightingColorFilter import android.view.View import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import io.reactivex.Observer import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.session_item.* import org.mozilla.fenix.R import org.mozilla.fenix.home.sessioncontrol.ArchivedSession import org.mozilla.fenix.home.sessioncontrol.ArchivedSessionAction import org.mozilla.fenix.home.sessioncontrol.SessionControlAction import org.mozilla.fenix.home.sessioncontrol.onNext import java.net.URL import java.text.SimpleDateFormat import java.util.Locale import java.util.Calendar import java.util.Date private const val NUMBER_OF_URLS_TO_DISPLAY = 5 private const val LONGEST_HOST_ON_INTERNET_LENGTH = 64 private val timeFormatter = SimpleDateFormat("h:mm a", Locale.US) private val monthFormatter = SimpleDateFormat("M", Locale.US) private val dayFormatter = SimpleDateFormat("d", Locale.US) private val dayOfWeekFormatter = SimpleDateFormat("EEEE", Locale.US) val ArchivedSession.formattedSavedAt: String get() = { val isSameDay: (Calendar, Calendar) -> Boolean = { a, b -> a.get(Calendar.ERA) == b.get(Calendar.ERA) && a.get(Calendar.YEAR) == b.get(Calendar.YEAR) && a.get(Calendar.DAY_OF_YEAR) == b.get(Calendar.DAY_OF_YEAR) } val parse: (Date) -> String = { date -> val dateCal = Calendar.getInstance().apply { time = date } val today = Calendar.getInstance() val yesterday = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, -1) } val time = timeFormatter.format(date) val month = monthFormatter.format(date) val day = dayFormatter.format(date) val dayOfWeek = dayOfWeekFormatter.format(date) when { isSameDay(dateCal, today) -> "Today @ $time" isSameDay(dateCal, yesterday) -> "Yesterday @ $time" else -> "$dayOfWeek $month/$day @ $time" } } parse(Date(savedAt)) }() val ArchivedSession.titles: String get() = { // Until we resolve (https://github.com/mozilla-mobile/fenix/issues/532) we // just want to grab the host from the URL @SuppressWarnings("TooGenericExceptionCaught") val urlFormatter: (String) -> String = { url -> var formattedURL = try { URL(url).host } catch (e: Exception) { url } if (formattedURL.length > LONGEST_HOST_ON_INTERNET_LENGTH) { formattedURL = formattedURL.take(LONGEST_HOST_ON_INTERNET_LENGTH).plus("...") } formattedURL } urls .take(NUMBER_OF_URLS_TO_DISPLAY) .joinToString(", ", transform = urlFormatter) }() val ArchivedSession.extrasLabel: Int get() = maxOf(urls.size - NUMBER_OF_URLS_TO_DISPLAY, 0) class SessionViewHolder( view: View, private val actionEmitter: Observer, override val containerView: View? = view ) : RecyclerView.ViewHolder(view), LayoutContainer { internal var session: ArchivedSession? = null init { session_item.setOnClickListener { session?.apply { actionEmitter.onNext(ArchivedSessionAction.Select(this)) } } session_card_overflow_button.setOnClickListener { session?.apply { actionEmitter.onNext(ArchivedSessionAction.MenuTapped(this)) } } session_card_share_button.setOnClickListener { session?.apply { actionEmitter.onNext(ArchivedSessionAction.ShareTapped(this)) } } } fun bind(session: ArchivedSession) { this.session = session val color = availableColors[(session.id % availableColors.size).toInt()] session_card_thumbnail.colorFilter = LightingColorFilter(ContextCompat.getColor(itemView.context, color), Color.BLACK) session_card_timestamp.text = session.formattedSavedAt session_card_titles.text = session.titles session_card_extras.text = if (session.extrasLabel > 0) { "+${session.extrasLabel} sites..." } else { "" } } companion object { private val availableColors = listOf( R.color.session_placeholder_blue, R.color.session_placeholder_green, R.color.session_placeholder_orange, R.color.session_placeholder_purple, R.color.session_placeholder_pink ) const val LAYOUT_ID = R.layout.session_item } }