Skip to content

Commit

Permalink
Merge branch 'hotfix/5.2.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
ccomeaux committed Mar 25, 2016
2 parents a635b9d + ecd7f19 commit d27b97a
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 308 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

Version 5.2.2
-------------
* Improve H-Index calculations
* Bug fixes

Version 5.2.1
-------------
* Fix play logging issues
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ android {
applicationId "com.boardgamegeek"
minSdkVersion 9
targetSdkVersion 23
versionCode 53
versionName "5.2.1"
versionCode 54
versionName "5.2.2"
buildConfigField "String", "BRANCH", "\"" + getBranchName() + "\""
}
buildTypes {
Expand Down
70 changes: 10 additions & 60 deletions app/src/main/java/com/boardgamegeek/service/SyncService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,21 @@

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.NotificationCompat;
import android.text.SpannableString;

import com.boardgamegeek.R;
import com.boardgamegeek.auth.Authenticator;
import com.boardgamegeek.model.Play;
import com.boardgamegeek.provider.BggContract;
import com.boardgamegeek.provider.BggContract.Plays;
import com.boardgamegeek.ui.PlayStatsActivity;
import com.boardgamegeek.ui.PlaysActivity;
import com.boardgamegeek.ui.model.PlayStats;
import com.boardgamegeek.util.NotificationUtils;
import com.boardgamegeek.util.PreferencesUtils;
import com.boardgamegeek.util.StringUtils;

public class SyncService extends Service {
public static final String EXTRA_SYNC_TYPE = "com.boardgamegeek.SYNC_TYPE";
Expand All @@ -48,8 +38,6 @@ public class SyncService extends Service {
public static final String TIMESTAMP_PLAYS_NEWEST_DATE = "com.boardgamegeek.TIMESTAMP_PLAYS_NEWEST_DATE";
public static final String TIMESTAMP_PLAYS_OLDEST_DATE = "com.boardgamegeek.TIMESTAMP_PLAYS_OLDEST_DATE";

private static final int INVALID_H_INDEX = -1;

private static final Object SYNC_ADAPTER_LOCK = new Object();
@Nullable private static SyncAdapter syncAdapter = null;

Expand Down Expand Up @@ -129,65 +117,27 @@ public static boolean clearPlays(Context context) {

public static void hIndex(@NonNull Context context) {
int hIndex = calculateHIndex(context);
if (hIndex != INVALID_H_INDEX) {
int oldHIndex = PreferencesUtils.getHIndex(context);
if (oldHIndex != hIndex) {
PreferencesUtils.putHIndex(context, hIndex);
notifyHIndex(context, hIndex, oldHIndex);
}
}
PreferencesUtils.updateHIndex(context, hIndex);
}

private static int calculateHIndex(@NonNull Context context) {
int hIndex = INVALID_H_INDEX;
Cursor cursor = null;
try {
Uri uri = Plays.CONTENT_SIMPLE_URI.buildUpon()
.appendQueryParameter(BggContract.QUERY_KEY_GROUP_BY, BggContract.PlayItems.OBJECT_ID)
.build();
cursor = context.getContentResolver().query(
uri, new String[] { Plays.SUM_QUANTITY },
Plays.SYNC_STATUS + "=?", new String[] { String.valueOf(Play.SYNC_STATUS_SYNCED) },
Plays.SUM_QUANTITY + " DESC");
PlayStats.getUri(),
PlayStats.PROJECTION,
PlayStats.getSelection(context),
PlayStats.getSelectionArgs(context),
PlayStats.getSortOrder());
if (cursor != null) {
int i = 1;
while (cursor.moveToNext()) {
int numPlays = cursor.getInt(0);
if (i > numPlays) {
hIndex = i - 1;
break;
}
if (numPlays == 0) {
hIndex = 0;
break;
}
i++;
}
if (hIndex == INVALID_H_INDEX) {
hIndex = cursor.getCount();
}
PlayStats stats = PlayStats.fromCursor(cursor);
return stats.getHIndex();
}
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return hIndex;
}

private static void notifyHIndex(@NonNull Context context, int hIndex, int oldHIndex) {
@StringRes int messageId;
if (hIndex > oldHIndex) {
messageId = R.string.sync_notification_h_index_increase;
} else {
messageId = R.string.sync_notification_h_index_decrease;
}
SpannableString ss = StringUtils.boldSecondString(context.getString(messageId), String.valueOf(hIndex));
Intent intent = new Intent(context, PlayStatsActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = NotificationUtils
.createNotificationBuilder(context, R.string.sync_notification_title_h_index, PlaysActivity.class)
.setContentText(ss).setContentIntent(pi);
NotificationUtils.notify(context, NotificationUtils.ID_H_INDEX, builder);
return PreferencesUtils.INVALID_H_INDEX;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public void onPaletteGenerated(Palette palette) {

@DebugLog
private void colorize(Palette palette) {
if (palette == null) {
if (palette == null || !isAdded()) {
return;
}
@SuppressWarnings("deprecation") Palette.Swatch swatch = PaletteUtils.getInverseSwatch(palette, getResources().getColor(R.color.info_background));
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/boardgamegeek/ui/GameFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ public Loader<Cursor> onCreateLoader(int id, Bundle data) {
break;
case PlaysQuery._TOKEN:
loader = new CursorLoader(getActivity(), Plays.CONTENT_URI, PlaysQuery.PROJECTION,
PlayItems.OBJECT_ID + "=? AND " + Plays.SYNC_STATUS + " !=?" ,
PlayItems.OBJECT_ID + "=? AND " + Plays.SYNC_STATUS + " !=?",
new String[] { String.valueOf(gameId), String.valueOf(Play.SYNC_STATUS_PENDING_DELETE) }, null);
break;
case ColorQuery._TOKEN:
Expand Down Expand Up @@ -378,7 +378,7 @@ public void onPaletteGenerated(Palette palette) {

@DebugLog
private void colorize() {
if (palette == null || primaryInfoContainer == null) {
if (palette == null || primaryInfoContainer == null || isAdded()) {
return;
}
Palette.Swatch swatch = PaletteUtils.getInverseSwatch(palette, getResources().getColor(R.color.info_background));
Expand Down
147 changes: 75 additions & 72 deletions app/src/main/java/com/boardgamegeek/ui/GeekListItemFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,127 +35,127 @@
public class GeekListItemFragment extends Fragment implements ImageUtils.Callback {
private static final int TIME_HINT_UPDATE_INTERVAL = 30000; // 30 sec

private Handler mHandler = new Handler();
private Runnable mUpdaterRunnable = null;
private String mOrder;
private String mTitle;
private String mType;
private int mImageId;
private String mUsername;
private int mThumbs;
private long mPostedDate;
private long mEditedDate;
private String mBody;
private Palette.Swatch mSwatch;

private ViewGroup mRootView;
@SuppressWarnings("unused") @InjectView(R.id.hero_container) View mHeroContainer;
@SuppressWarnings("unused") @InjectView(R.id.header_container) View mHeaderContainer;
@SuppressWarnings("unused") @InjectView(R.id.order) TextView mOrderView;
@SuppressWarnings("unused") @InjectView(R.id.title) TextView mTitleView;
@SuppressWarnings("unused") @InjectView(R.id.type) TextView mTypeView;
@SuppressWarnings("unused") @InjectView(R.id.image) ImageView mImageView;
@SuppressWarnings("unused") @InjectView(R.id.author_container) View mAuthorContainer;
@SuppressWarnings("unused") @InjectView(R.id.username) TextView mUsernameView;
@SuppressWarnings("unused") @InjectView(R.id.thumbs) TextView mThumbsView;
@SuppressWarnings("unused") @InjectView(R.id.posted_date) TextView mPostedDateView;
@SuppressWarnings("unused") @InjectView(R.id.edited_date) TextView mEditedDateView;
@SuppressWarnings("unused") @InjectView(R.id.body) WebView mBodyView;
private Handler timeHintUpdateHandler = new Handler();
private Runnable timeHintUpdateRunnable = null;
private String order;
private String title;
private String type;
private int imageId;
private String username;
private int numberOfThumbs;
private long postedDate;
private long editedDate;
private String body;
private Palette.Swatch swatch;

private ViewGroup rootView;
@SuppressWarnings("unused") @InjectView(R.id.hero_container) View heroContainer;
@SuppressWarnings("unused") @InjectView(R.id.header_container) View headerContainer;
@SuppressWarnings("unused") @InjectView(R.id.order) TextView orderView;
@SuppressWarnings("unused") @InjectView(R.id.title) TextView titleView;
@SuppressWarnings("unused") @InjectView(R.id.type) TextView typeView;
@SuppressWarnings("unused") @InjectView(R.id.image) ImageView imageView;
@SuppressWarnings("unused") @InjectView(R.id.author_container) View authorContainer;
@SuppressWarnings("unused") @InjectView(R.id.username) TextView usernameView;
@SuppressWarnings("unused") @InjectView(R.id.thumbs) TextView thumbsView;
@SuppressWarnings("unused") @InjectView(R.id.posted_date) TextView postedDateView;
@SuppressWarnings("unused") @InjectView(R.id.edited_date) TextView editedDateView;
@SuppressWarnings("unused") @InjectView(R.id.body) WebView bodyView;
@SuppressWarnings("unused") @InjectViews({
R.id.username,
R.id.thumbs,
R.id.posted_date,
R.id.edited_date
}) List<TextView> mColorizedTextViews;
}) List<TextView> colorizedTextViews;

private final ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener
= new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ImageUtils.resizeImagePerAspectRatio(mImageView, mRootView.getHeight() / 3, mHeroContainer);
ImageUtils.resizeImagePerAspectRatio(imageView, rootView.getHeight() / 3, heroContainer);
}
};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
timeHintUpdateHandler = new Handler();
final Intent intent = UIUtils.fragmentArgumentsToIntent(getArguments());
mOrder = intent.getStringExtra(ActivityUtils.KEY_ORDER);
mTitle = intent.getStringExtra(ActivityUtils.KEY_NAME);
mType = intent.getStringExtra(ActivityUtils.KEY_TYPE);
mImageId = intent.getIntExtra(ActivityUtils.KEY_IMAGE_ID, BggContract.INVALID_ID);
mUsername = intent.getStringExtra(ActivityUtils.KEY_USERNAME);
mThumbs = intent.getIntExtra(ActivityUtils.KEY_THUMBS, 0);
mPostedDate = intent.getLongExtra(ActivityUtils.KEY_POSTED_DATE, 0);
mEditedDate = intent.getLongExtra(ActivityUtils.KEY_EDITED_DATE, 0);
mBody = intent.getStringExtra(ActivityUtils.KEY_BODY);
order = intent.getStringExtra(ActivityUtils.KEY_ORDER);
title = intent.getStringExtra(ActivityUtils.KEY_NAME);
type = intent.getStringExtra(ActivityUtils.KEY_TYPE);
imageId = intent.getIntExtra(ActivityUtils.KEY_IMAGE_ID, BggContract.INVALID_ID);
username = intent.getStringExtra(ActivityUtils.KEY_USERNAME);
numberOfThumbs = intent.getIntExtra(ActivityUtils.KEY_THUMBS, 0);
postedDate = intent.getLongExtra(ActivityUtils.KEY_POSTED_DATE, 0);
editedDate = intent.getLongExtra(ActivityUtils.KEY_EDITED_DATE, 0);
body = intent.getStringExtra(ActivityUtils.KEY_BODY);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = (ViewGroup) inflater.inflate(R.layout.fragment_geeklist_item, container, false);
ButterKnife.inject(this, mRootView);
rootView = (ViewGroup) inflater.inflate(R.layout.fragment_geeklist_item, container, false);
ButterKnife.inject(this, rootView);

applySwatch();
ScrimUtils.applyDefaultScrim(mHeaderContainer);
ViewTreeObserver vto = mRootView.getViewTreeObserver();
ScrimUtils.applyDefaultScrim(headerContainer);
ViewTreeObserver vto = rootView.getViewTreeObserver();
if (vto.isAlive()) {
vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
}

mOrderView.setText(mOrder);
mTitleView.setText(mTitle);
mTypeView.setText(mType);
ImageUtils.safelyLoadImage(mImageView, mImageId, this);
mUsernameView.setText(mUsername);
mThumbsView.setText(getString(R.string.thumbs_suffix, mThumbs));
mPostedDateView.setTag(mPostedDate);
mEditedDateView.setTag(mEditedDate);
String content = new XmlConverter().toHtml(mBody);
UIUtils.setWebViewText(mBodyView, content);
orderView.setText(order);
titleView.setText(title);
typeView.setText(type);
ImageUtils.safelyLoadImage(imageView, imageId, this);
usernameView.setText(username);
thumbsView.setText(getString(R.string.thumbs_suffix, numberOfThumbs));
postedDateView.setTag(postedDate);
editedDateView.setTag(editedDate);
String content = new XmlConverter().toHtml(body);
UIUtils.setWebViewText(bodyView, content);

updateTimeBasedUi();
if (mUpdaterRunnable != null) {
mHandler.removeCallbacks(mUpdaterRunnable);
if (timeHintUpdateRunnable != null) {
timeHintUpdateHandler.removeCallbacks(timeHintUpdateRunnable);
}
mUpdaterRunnable = new Runnable() {
timeHintUpdateRunnable = new Runnable() {
@Override
public void run() {
updateTimeBasedUi();
mHandler.postDelayed(mUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
timeHintUpdateHandler.postDelayed(timeHintUpdateRunnable, TIME_HINT_UPDATE_INTERVAL);
}
};
mHandler.postDelayed(mUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
timeHintUpdateHandler.postDelayed(timeHintUpdateRunnable, TIME_HINT_UPDATE_INTERVAL);

return mRootView;
return rootView;
}

private void updateTimeBasedUi() {
if (!isAdded()) {
return;
}
if (mPostedDateView != null) {
mPostedDateView.setText(getString(R.string.posted_prefix, DateTimeUtils.formatForumDate(getActivity(), mPostedDate)));
if (postedDateView != null) {
postedDateView.setText(getString(R.string.posted_prefix, DateTimeUtils.formatForumDate(getActivity(), postedDate)));
}
if (mEditedDateView != null) {
mEditedDateView.setText(getString(R.string.edited_prefix, DateTimeUtils.formatForumDate(getActivity(), mEditedDate)));
if (editedDateView != null) {
editedDateView.setText(getString(R.string.edited_prefix, DateTimeUtils.formatForumDate(getActivity(), editedDate)));
}
}

@Override
public void onResume() {
super.onResume();
if (mUpdaterRunnable != null) {
mHandler.postDelayed(mUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
if (timeHintUpdateRunnable != null) {
timeHintUpdateHandler.postDelayed(timeHintUpdateRunnable, TIME_HINT_UPDATE_INTERVAL);
}
}

@Override
public void onPause() {
super.onPause();
if (mUpdaterRunnable != null) {
mHandler.removeCallbacks(mUpdaterRunnable);
if (timeHintUpdateRunnable != null) {
timeHintUpdateHandler.removeCallbacks(timeHintUpdateRunnable);
}
}

Expand All @@ -169,11 +169,11 @@ public void onDestroyView() {
@Override
public void onDestroy() {
super.onDestroy();
if (mRootView == null) {
if (rootView == null) {
return;
}

ViewTreeObserver vto = mRootView.getViewTreeObserver();
ViewTreeObserver vto = rootView.getViewTreeObserver();
if (vto.isAlive()) {
if (VersionUtils.hasJellyBean()) {
vto.removeOnGlobalLayoutListener(mGlobalLayoutListener);
Expand All @@ -186,14 +186,17 @@ public void onDestroy() {

@Override
public void onPaletteGenerated(Palette palette) {
mSwatch = PaletteUtils.getInverseSwatch(palette, getResources().getColor(R.color.info_background));
if (!isAdded()) {
return;
}
swatch = PaletteUtils.getInverseSwatch(palette, getResources().getColor(R.color.info_background));
applySwatch();
}

private void applySwatch() {
if (mAuthorContainer != null && mSwatch != null) {
mAuthorContainer.setBackgroundColor(mSwatch.getRgb());
ButterKnife.apply(mColorizedTextViews, PaletteUtils.colorTextViewOnBackgroundSetter, mSwatch);
if (authorContainer != null && swatch != null) {
authorContainer.setBackgroundColor(swatch.getRgb());
ButterKnife.apply(colorizedTextViews, PaletteUtils.colorTextViewOnBackgroundSetter, swatch);
}
}
}
Loading

0 comments on commit d27b97a

Please sign in to comment.