/* * Copyright 2014, 2015, 2016 Anael Mobilia * * This file is part of NextINpact-Unofficial. * * NextINpact-Unofficial is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NextINpact-Unofficial is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NextINpact-Unofficial. If not, see <http://www.gnu.org/licenses/> */ package com.pcinpact; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.AbsListView; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import com.pcinpact.adapters.ItemsAdapter; import com.pcinpact.datastorage.DAO; import com.pcinpact.items.CommentaireItem; import com.pcinpact.items.Item; import com.pcinpact.network.AsyncHTMLDownloader; import com.pcinpact.network.RefreshDisplayInterface; import com.pcinpact.utils.Constantes; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; /** * Affichage des commentaires. * * @author Anael */ public class CommentairesActivity extends AppCompatActivity implements RefreshDisplayInterface { /** * Les commentaires. */ private ArrayList<CommentaireItem> mesCommentaires = new ArrayList<>(); /** * ID de l'article. */ private int articleID; /** * ID du dernier commentaire lu */ private int idDernierCommentaireLu; /** * ItemAdapter. */ private ItemsAdapter monItemsAdapter; /** * accès à la BDD. */ private DAO monDAO; /** * téléchargement en cours ? */ private int dlInProgress = 0; /** * Fin des commentaires ? */ private Boolean isFinCommentaires = false; /** * téléchargement de TOUS les commentaires ? */ private Boolean isChargementTotal = false; /** * Réouverture au dernier commentaire lu ? */ private Boolean reouverture; /** * Bouton pour télécharger 10 commentaires en plus. */ private Button buttonDl10Commentaires; /** * TextView "Dernière synchro...". */ private TextView headerTextView; /** * ListView. */ private ListView monListView; /** * SwipeRefreshLayout. */ private SwipeRefreshLayout monSwipeRefreshLayout; /** * Menu */ private Menu monMenu; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Gestion du thème sombre (option utilisateur) Boolean isThemeSombre = Constantes.getOptionBoolean(getApplicationContext(), R.string.idOptionThemeSombre, R.bool.defautOptionThemeSombre); if (isThemeSombre) { // Si actif, on applique le style setTheme(R.style.NextInpactThemeFonce); } // Partie graphique setContentView(R.layout.activity_liste_commentaires); // Gestion du swipe refresh monSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container); // onRefresh monSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { // Chargement de tous les commentaires isChargementTotal = true; refreshListeCommentaires(); } }); headerTextView = (TextView) findViewById(R.id.header_text); // Liste des commentaires monListView = (ListView) this.findViewById(R.id.listeCommentaires); // Footer : bouton "Charger plus de commentaires" buttonDl10Commentaires = new Button(this); buttonDl10Commentaires.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // téléchargement de 10 commentaires en plus refreshListeCommentaires(); } }); buttonDl10Commentaires.setText(getResources().getString(R.string.commentairesPlusDeCommentaires)); monListView.addFooterView(buttonDl10Commentaires); // Adapter pour l'affichage des données monItemsAdapter = new ItemsAdapter(getApplicationContext(), getLayoutInflater(), new ArrayList<Item>()); monListView.setAdapter(monItemsAdapter); // ID de l'article concerné articleID = getIntent().getExtras().getInt("ARTICLE_ID"); // J'active la BDD monDAO = DAO.getInstance(getApplicationContext()); // Je charge mes articles mesCommentaires.addAll(monDAO.chargerCommentairesTriParDate(articleID)); // MàJ de l'affichage monItemsAdapter.updateListeItems(mesCommentaires); // Je fait remarquer que le contenu à changé monItemsAdapter.notifyDataSetChanged(); /** * Réouverture au dernier commentaire lu */ reouverture = Constantes.getOptionBoolean(getApplicationContext(), R.string.idOptionPositionCommentaire, R.bool.defautOptionPositionCommentaire); if (reouverture) { idDernierCommentaireLu = monDAO.getDernierCommentaireLu(articleID); monListView.setSelection(idDernierCommentaireLu); } // MàJ de la date de dernier refresh majDateRefresh(); } /** * Charge les commentaires suivants. */ private void refreshListeCommentaires() { // DEBUG if (Constantes.DEBUG) { Log.i("CommentairesActivity", "refreshListeCommentaires()"); } int idDernierCommentaire = 0; // Si j'ai des commentaires, je récupère le nombre de commentaires if (!mesCommentaires.isEmpty()) { idDernierCommentaire = mesCommentaires.size(); } // Le cast en int supprime la partie après la virgule int maPage = (int) Math.floor((idDernierCommentaire / Constantes.NB_COMMENTAIRES_PAR_PAGE) + 1); // Création de l'URL String monURL = Constantes.NEXT_INPACT_URL_COMMENTAIRES + "?" + Constantes.NEXT_INPACT_URL_COMMENTAIRES_PARAM_ARTICLE_ID + "=" + articleID + "&" + Constantes.NEXT_INPACT_URL_COMMENTAIRES_PARAM_NUM_PAGE + "=" + maPage; // Ma tâche de DL AsyncHTMLDownloader monAHD = new AsyncHTMLDownloader(this, Constantes.HTML_COMMENTAIRES, monURL, monDAO, getApplicationContext()); // DEBUG if (Constantes.DEBUG) { Log.i("CommentairesActivity", "refreshListeCommentaires() : lancement téléchargement"); } // Lancement du téléchargement if (monAHD.run()) { // Lancement de l'animation de téléchargement debutTelechargement(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Conservation du menu monMenu = menu; // Je charge mon menu dans l'actionBar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.activity_commentaires_actions, menu); // Configuration du onScroll de la listview configOnScroll(); return true; } /** * Configuration du scroll (listview) : Méthode séparée pour gestion propre des boutons du menu */ private void configOnScroll() { // Système de rafraichissement de la vue monListView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // Dernier item affiché int lastVisibleItem = firstVisibleItem + visibleItemCount; /** * Gestion du téléchargement */ if (lastVisibleItem >= (totalItemCount - 1)) { // (# du 1er commentaire affiché + nb d'items affichés) == (nb total d'item dans la liste - [bouton footer]) // téléchargement automatique en continu des commentaires ? Boolean telecharger = Constantes.getOptionBoolean(getApplicationContext(), R.string.idOptionCommentairesTelechargementContinu, R.bool.defautOptionCommentairesTelechargementContinu); // Si l'utilisateur le veut && je ne télécharge pas déjà && la fin des commentaires n'est pas atteinte if (telecharger && dlInProgress == 0 && !isFinCommentaires) { // téléchargement de 10 commentaires en plus refreshListeCommentaires(); // DEBUG if (Constantes.DEBUG) { Log.i("CommentairesActivity", "onScroll() - Chargement continu -> lancement chargement commentaires - " + visibleItemCount); } } } /** * Gestion de la réouverture au dernier commentaire lu */ // Et qu'on a lu plus de commentaires if (reouverture && lastVisibleItem > idDernierCommentaireLu) { /** * Enregistrement de l'id du dernier commentaire affiché */ monDAO.setDernierCommentaireLu(articleID, lastVisibleItem); // Mise à jour de la copie locale idDernierCommentaireLu = lastVisibleItem; // DEBUG if (Constantes.DEBUG) { Log.d("CommentairesActivity", "onScroll() - setDernierCommentaireLu(" + articleID + ", " + lastVisibleItem + ")"); } } /** * Gestion du SwipeRefreshLayout */ int topRowVerticalPosition; if (monListView == null || monListView.getChildCount() == 0) { topRowVerticalPosition = 0; } else { topRowVerticalPosition = monListView.getFirstVisiblePosition(); } // DEBUG if (Constantes.DEBUG) { Log.d("CommentairesActivity", "onScroll() - SwipeRefreshLayout - topRowVerticalPosition : " + topRowVerticalPosition); } monSwipeRefreshLayout.setEnabled(topRowVerticalPosition <= 0); } }); } @Override public boolean onOptionsItemSelected(final MenuItem pItem) { // Rafraichir la liste des commentaires if (pItem.getItemId() == R.id.action_refresh) { // téléchargement de TOUS les commentaires isChargementTotal = true; // Lancement du premier chargement refreshListeCommentaires(); } return super.onOptionsItemSelected(pItem); } /** * Lance les animations indiquant un téléchargement. */ private void debutTelechargement() { // DEBUG if (Constantes.DEBUG) { Log.i("CommentairesActivity", "debutTelechargement() : " + dlInProgress); } // Lancement de l'animation le cas échéant if (dlInProgress == 0) { // Couleurs du RefreshLayout monSwipeRefreshLayout.setColorSchemeColors(ContextCompat.getColor(getApplicationContext(), R.color.refreshBleu), ContextCompat.getColor(getApplicationContext(), R.color.refreshOrange)); // Animation du RefreshLayout monSwipeRefreshLayout.setRefreshing(true); // MàJ du bouton du footer buttonDl10Commentaires.setText(getString(R.string.commentairesChargement)); // Grisage de l'icône d'action MenuItem monItem = monMenu.findItem(R.id.action_refresh); monItem.getIcon().setAlpha(130); monItem.setEnabled(false); } // J'enregistre l'état dlInProgress++; } /** * Arrête les animations indiquant un téléchargement. */ private void finTelechargement() { // DEBUG if (Constantes.DEBUG) { Log.i("CommentairesActivity", "finTelechargement() " + dlInProgress); } // J'enregistre l'état dlInProgress--; // Si plus de téléchargement en cours if (dlInProgress == 0) { // Arrêt du RefreshLayout monSwipeRefreshLayout.setRefreshing(false); // MàJ du bouton du footer buttonDl10Commentaires.setText(getString(R.string.commentairesPlusDeCommentaires)); // Dégrisage de l'icône MenuItem monItem = monMenu.findItem(R.id.action_refresh); monItem.getIcon().setAlpha(255); monItem.setEnabled(true); } } @Override public void downloadHTMLFini(final String uneURL, final ArrayList<? extends Item> desItems) { // Retour vide ? Fin ou pas de connexion if (desItems.isEmpty()) { // Je note qu'il n'y a plus de commentaires isFinCommentaires = true; // Chargement de TOUS les commentaires ? if (isChargementTotal) { // On enlève le marqueur isChargementTotal = false; } if (Constantes.DEBUG) { Log.i("CommentairesActivity", "downloadHTMLFini() - fin des commentaires"); } } else { // J'enregistre en mémoire les nouveaux commentaires for (Item unItem : desItems) { // Je l'enregistre en mémoire mesCommentaires.add((CommentaireItem) unItem); } // Tri des commentaires par ID Collections.sort(mesCommentaires); // Je met à jour les données monItemsAdapter.updateListeItems(mesCommentaires); // Je notifie le changement pour un rafraichissement du contenu monItemsAdapter.notifyDataSetChanged(); // Je note que je ne suis pas à la fin des commentaires isFinCommentaires = false; // Chargement de TOUS les commentaires ? if (isChargementTotal) { // Lancement du prochain téléchargement... refreshListeCommentaires(); } } // Je MàJ la date du dernier refresh majDateRefresh(); // Arrêt des gris-gris en GUI finTelechargement(); } @Override public void downloadImageFini(final String uneURL) { // Aucune action. } /** * MàJ de la date de dernière MàJ. */ private void majDateRefresh() { long dernierRefresh = monDAO.chargerDateRefresh(articleID); if (dernierRefresh == 0) { // Jamais synchro... headerTextView.setText(getString(R.string.lastUpdateNever)); } else { String monTexte = getString(R.string.lastUpdate) + new SimpleDateFormat(Constantes.FORMAT_DATE_DERNIER_REFRESH, Constantes.LOCALE).format(dernierRefresh); // Une MàJ à déjà été faite headerTextView.setText(monTexte); } } }