<commit_before>package com.thangiee.LoLHangouts.fragments

import android.app.Activity
import android.os.{Bundle, Handler}
import android.view.{LayoutInflater, View, ViewGroup}
import android.widget.ImageView
import com.devspark.progressfragment.ProgressFragment
import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter
import com.thangiee.LoLHangouts.R
import com.thangiee.LoLHangouts.api.core.LoLChat
import com.thangiee.LoLHangouts.utils.Events.{RefreshFriendCard, RefreshFriendList}
import com.thangiee.LoLHangouts.views.{FriendBaseCard, FriendOffCard, FriendOnCard}
import de.greenrobot.event.EventBus
import de.keyboardsurfer.android.widget.crouton.{Crouton, Configuration, Style}
import it.gmariotti.cardslib.library.internal.CardArrayAdapter
import it.gmariotti.cardslib.library.view.CardListView
import org.jivesoftware.smack.packet.Presence
import org.scaloid.common._

import scala.collection.JavaConversions._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

case class FriendListFragment() extends ProgressFragment with TFragment {
  private val cards = scala.collection.mutable.ArrayBuffer[FriendBaseCard]()
  private var cardArrayAdapter: CardArrayAdapter = _
  private var handler: Handler = _
  private var lock = false
  private lazy val autoRefreshTask = new Runnable {
    override def run(): Unit = {
      info("[*] Auto refresh friend list")
      refreshFriendList()
      handler.postDelayed(this, 60 * 1000)
    }
  }

  override def onAttach(activity: Activity): Unit = {
    super.onAttach(activity)
    cardArrayAdapter = new CardArrayAdapter(activity, cards)
  }

  override def onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle): View = {
    EventBus.getDefault.register(this)
    view = inflater.inflate(R.layout.friend_list_pane, null)
    handler = new Handler()
    inflater.inflate(R.layout.progress_container, container, false)
  }

  override def onResume(): Unit = {
    super.onResume()
    setContentView(view)
    setContentShown(false) // show loading bar
    val listView = find[CardListView](R.id.list_summoner_card)

    populateFriendCardList.onComplete { _ ⇒
      runOnUiThread {
        cardArrayAdapter.setNotifyOnChange(false)
        cardArrayAdapter.setInnerViewTypeCount(2) // important with different inner layout
        val animationAdapter = new AlphaInAnimationAdapter(cardArrayAdapter)
        animationAdapter.setAbsListView(listView)
        listView.setExternalAdapter(animationAdapter, cardArrayAdapter)
        setContentShown(true) // hide loading bar and show content
      }
    }
    // automatically refresh friend list every 1 minute
    handler.postDelayed(autoRefreshTask, 60 * 1000)
  }

  override def onStart(): Unit = {
    super.onStart()
    find[ImageView](R.id.img_friend_list_bg).setImageResource(R.drawable.summoners_rift2)
    // show warning when in offline mode
    if (LoLChat.presenceType() == Presence.Type.unavailable) {
      val customStyle = new Style.Builder().setBackgroundColor(R.color.offline_warning).build()
      Crouton.makeText(ctx.asInstanceOf[Activity], R.string.offline_mode_warning.r2String, customStyle)
        .setConfiguration(new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build()).show()
    }
  }

  override def onPause(): Unit = {
    handler.removeCallbacks(autoRefreshTask)
    super.onPause()
  }

  override def onStop(): Unit = {
    find[ImageView](R.id.img_friend_list_bg).setImageDrawable(null)
    super.onStop()
  }

  override def onDestroy(): Unit = {
    EventBus.getDefault.unregister(this)
    super.onDestroy()
  }

  def findCardByName(name: String): Option[FriendBaseCard] = {
    for (i <- 0 until cardArrayAdapter.getCount) {
      val baseCard = cardArrayAdapter.getItem(i).asInstanceOf[FriendBaseCard] // get the card view
      if (baseCard.cardName == name) return Some(baseCard)
    }
    None
  }

  private def refreshFriendList(): Unit = {
    // lock use to prevent multiple calls to refresh friend list while it is already refreshing
    if (!lock)
      populateFriendCardList.onComplete(_ ⇒ runOnUiThread(cardArrayAdapter.notifyDataSetChanged()))
    else
      info("[-] Refresh friend list blocked")
  }

  private def populateFriendCardList: Future[Unit] = {
    lock = true
    Future[Unit] {
      val (onFriends, offFriends) = (LoLChat.onlineFriends, LoLChat.offlineFriends)
      runOnUiThread {
        cards.clear()
        cards.++=(onFriends.map(f => FriendOnCard(f)))
        cards.++=(offFriends.map(f => FriendOffCard(f)))
        lock = false
      }
    }
  }

  def onEvent(event: RefreshFriendList): Unit = { refreshFriendList() }

  def onEventMainThread(event: RefreshFriendCard): Unit = {
    info("[*]onEvent: request to refresh " + event.friend.name + "friend card")
    findCardByName(event.friend.name) match {
      case Some(card) => info("[+]Found card"); card.refreshCard()
      case None => warn("[-]No card found")
    }
    cardArrayAdapter.notifyDataSetChanged()
  }
}<commit_msg>also block RefreshFriendCard event when friend list is currently refreshing<commit_after>package com.thangiee.LoLHangouts.fragments

import android.app.{Notification, Activity}
import android.media.MediaPlayer
import android.os.{Build, Bundle, Handler}
import android.view.{LayoutInflater, View, ViewGroup}
import android.widget.ImageView
import com.devspark.progressfragment.ProgressFragment
import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter
import com.ruenzuo.messageslistview.models
import com.thangiee.LoLHangouts.R
import com.thangiee.LoLHangouts.api.core.LoLChat
import com.thangiee.LoLHangouts.utils.DB
import com.thangiee.LoLHangouts.utils.Events.{RefreshFriendCard, RefreshFriendList}
import com.thangiee.LoLHangouts.views.{FriendBaseCard, FriendOffCard, FriendOnCard}
import de.greenrobot.event.EventBus
import de.keyboardsurfer.android.widget.crouton.{Crouton, Configuration, Style}
import it.gmariotti.cardslib.library.internal.CardArrayAdapter
import it.gmariotti.cardslib.library.view.CardListView
import org.jivesoftware.smack.packet.Presence
import org.scaloid.common._

import scala.collection.JavaConversions._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

case class FriendListFragment() extends ProgressFragment with TFragment {
  private val cards = scala.collection.mutable.ArrayBuffer[FriendBaseCard]()
  private var cardArrayAdapter: CardArrayAdapter = _
  private var handler: Handler = _
  private var lock = false
  private lazy val autoRefreshTask = new Runnable {
    override def run(): Unit = {
      info("[*] Auto refresh friend list")
      refreshFriendList()
      handler.postDelayed(this, 60 * 1000)
    }
  }

  override def onAttach(activity: Activity): Unit = {
    super.onAttach(activity)
    cardArrayAdapter = new CardArrayAdapter(activity, cards)
  }

  override def onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle): View = {
    EventBus.getDefault.register(this)
    view = inflater.inflate(R.layout.friend_list_pane, null)
    handler = new Handler()
    inflater.inflate(R.layout.progress_container, container, false)
  }

  override def onResume(): Unit = {
    super.onResume()
    setContentView(view)
    setContentShown(false) // show loading bar
    val listView = find[CardListView](R.id.list_summoner_card)

    populateFriendCardList.onComplete { _ ⇒
      runOnUiThread {
        cardArrayAdapter.setNotifyOnChange(false)
        cardArrayAdapter.setInnerViewTypeCount(2) // important with different inner layout
        val animationAdapter = new AlphaInAnimationAdapter(cardArrayAdapter)
        animationAdapter.setAbsListView(listView)
        listView.setExternalAdapter(animationAdapter, cardArrayAdapter)
        setContentShown(true) // hide loading bar and show content
      }
    }
    // automatically refresh friend list every 1 minute
    handler.postDelayed(autoRefreshTask, 60 * 1000)
  }

  override def onStart(): Unit = {
    super.onStart()
    find[ImageView](R.id.img_friend_list_bg).setImageResource(R.drawable.summoners_rift2)
    // show warning when in offline mode
    if (LoLChat.presenceType() == Presence.Type.unavailable) {
      val customStyle = new Style.Builder().setBackgroundColor(R.color.offline_warning).build()
      Crouton.makeText(ctx.asInstanceOf[Activity], R.string.offline_mode_warning.r2String, customStyle)
        .setConfiguration(new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build()).show()
    }
  }

  override def onPause(): Unit = {
    handler.removeCallbacks(autoRefreshTask)
    super.onPause()
  }

  override def onStop(): Unit = {
    find[ImageView](R.id.img_friend_list_bg).setImageDrawable(null)
    super.onStop()
  }

  override def onDestroy(): Unit = {
    EventBus.getDefault.unregister(this)
    super.onDestroy()
  }

  def findCardByName(name: String): Option[FriendBaseCard] = {
    for (i <- 0 until cardArrayAdapter.getCount) {
      val baseCard = cardArrayAdapter.getItem(i).asInstanceOf[FriendBaseCard] // get the card view
      if (baseCard.cardName == name) return Some(baseCard)
    }
    None
  }

  private def refreshFriendList(): Unit = {
    // lock use to prevent multiple calls to refresh friend list while it is already refreshing
    if (!lock)
      populateFriendCardList.onComplete(_ ⇒ runOnUiThread(cardArrayAdapter.notifyDataSetChanged()))
    else
      info("[-] Refresh friend list blocked")
  }

  private def populateFriendCardList: Future[Unit] = {
    lock = true
    Future[Unit] {
      val (onFriends, offFriends) = (LoLChat.onlineFriends, LoLChat.offlineFriends)
      runOnUiThread {
        cards.clear()
        cards.++=(onFriends.map(f => FriendOnCard(f)))
        cards.++=(offFriends.map(f => FriendOffCard(f)))
        lock = false
      }
    }
  }

  def onEvent(event: RefreshFriendList): Unit = { refreshFriendList() }

  def onEventMainThread(event: RefreshFriendCard): Unit = {
    info("[*]onEvent: request to refresh " + event.friend.name + "friend card")
    // also block RefreshFriendCard event when friend list is currently refreshing
    if (!lock) {
      findCardByName(event.friend.name) match {
        case Some(card) => info("[+]Found card"); card.refreshCard()
        case None => warn("[-]No card found")
      }
      cardArrayAdapter.notifyDataSetChanged()
    } else {
      info("[-] Refresh friend's card blocked")
    }
  }
}
{'fraction_non_alphanumeric': 0.10194220748460445, 'fraction_numerical': 0.003221222169587873, 'mean_word_length': 4.151781356759395, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '531701', 'n_tokens_mistral': 3214, 'n_tokens_neox': 3119, 'n_words': 653}