Added countdown timer support.

This commit is contained in:
Pierre HUBERT 2018-08-29 10:15:04 +02:00
parent ee86c0c6e7
commit f9fc7227a5
7 changed files with 200 additions and 0 deletions

View File

@ -34,6 +34,11 @@ public enum PostTypes {
*/ */
PDF, PDF,
/**
* Countdown timer
*/
COUNTDOWN,
/** /**
* Unknown type * Unknown type
*/ */

View File

@ -375,6 +375,10 @@ public class PostsHelper {
post.setWebLink(webLink); post.setWebLink(webLink);
} }
//Get information about countdown timer (if any)
if(!json.isNull("time_end"))
post.setTime_end(json.getInt("time_end"));
return post; return post;
} }
@ -429,6 +433,9 @@ public class PostsHelper {
case "pdf": case "pdf":
return PostTypes.PDF; return PostTypes.PDF;
case "countdown":
return PostTypes.COUNTDOWN;
default: default:
return PostTypes.UNKNOWN; return PostTypes.UNKNOWN;

View File

@ -49,6 +49,9 @@ public class Post {
//Web link //Web link
private WebLink webLink; private WebLink webLink;
//Countdown timer
private int time_end;
//Set and get the ID of the post //Set and get the ID of the post
public void setId(int id) { public void setId(int id) {
@ -228,5 +231,14 @@ public class Post {
public void setWebLink(WebLink webLink) { public void setWebLink(WebLink webLink) {
this.webLink = webLink; this.webLink = webLink;
} }
//Set and get countdown time end
public int getTime_end() {
return time_end;
}
public void setTime_end(int time_end) {
this.time_end = time_end;
}
} }

View File

@ -60,4 +60,21 @@ public class StringsUtils {
Locale.getDefault()); Locale.getDefault());
return simpleDateFormat.format((long)1000*time); return simpleDateFormat.format((long)1000*time);
} }
/**
* Convert an integer into a string, making sure that the generated string respects an minimum
* size
*
* @param value The integer to convert
* @param size The size of string
* @return Generated string
*/
public static String EnsureZerosInNumberString(int value, int size){
StringBuilder stringBuilder = new StringBuilder(value + "");
while (stringBuilder.length() < size)
stringBuilder.insert(0, "0");
return stringBuilder.toString();
}
} }

View File

@ -22,6 +22,7 @@ import org.communiquons.android.comunic.client.data.models.UserInfo;
import org.communiquons.android.comunic.client.data.utils.Utilities; import org.communiquons.android.comunic.client.data.utils.Utilities;
import org.communiquons.android.comunic.client.ui.listeners.onPostUpdateListener; import org.communiquons.android.comunic.client.ui.listeners.onPostUpdateListener;
import org.communiquons.android.comunic.client.ui.utils.UiUtils; import org.communiquons.android.comunic.client.ui.utils.UiUtils;
import org.communiquons.android.comunic.client.ui.views.CountDownView;
import org.communiquons.android.comunic.client.ui.views.EditCommentContentView; import org.communiquons.android.comunic.client.ui.views.EditCommentContentView;
import org.communiquons.android.comunic.client.ui.views.EnlargeableWebImageView; import org.communiquons.android.comunic.client.ui.views.EnlargeableWebImageView;
import org.communiquons.android.comunic.client.ui.views.LikeButtonView; import org.communiquons.android.comunic.client.ui.views.LikeButtonView;
@ -54,6 +55,7 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
private static final int VIEW_TYPE_POST_MOVIE = 2; private static final int VIEW_TYPE_POST_MOVIE = 2;
private static final int VIEW_TYPE_POST_PDF = 3; private static final int VIEW_TYPE_POST_PDF = 3;
private static final int VIEW_TYPE_POST_WEBLINK = 4; private static final int VIEW_TYPE_POST_WEBLINK = 4;
private static final int VIEW_TYPE_POST_COUNTDOWN = 5;
/** /**
* Posts list * Posts list
@ -118,6 +120,9 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
case MOVIE: case MOVIE:
return VIEW_TYPE_POST_MOVIE; return VIEW_TYPE_POST_MOVIE;
case COUNTDOWN:
return VIEW_TYPE_POST_COUNTDOWN;
case TEXT: case TEXT:
default: default:
return VIEW_TYPE_POST_TEXT; return VIEW_TYPE_POST_TEXT;
@ -144,6 +149,9 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
case VIEW_TYPE_POST_MOVIE: case VIEW_TYPE_POST_MOVIE:
return new MoviePostHolder(view); return new MoviePostHolder(view);
case VIEW_TYPE_POST_COUNTDOWN:
return new CountdownPostHolder(view);
default: default:
return new TextPostHolder(view); return new TextPostHolder(view);
} }
@ -430,4 +438,28 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
mMovieView.setMovie(getPost(position).getMovie()); mMovieView.setMovie(getPost(position).getMovie());
} }
} }
/**
* Countdown post holder
*/
private class CountdownPostHolder extends TextPostHolder {
private CountDownView mCountDownView;
CountdownPostHolder(@NonNull View itemView) {
super(itemView);
mCountDownView = new CountDownView(getContext(), null);
getAdditionnalViewsLayout().addView(mCountDownView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
UiUtils.GetPixel(getContext(), 30)));
}
@Override
void bind(int position) {
super.bind(position);
mCountDownView.setTime_end(getPost(position).getTime_end());
}
}
} }

View File

@ -0,0 +1,104 @@
package org.communiquons.android.comunic.client.ui.views;
import android.content.Context;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.communiquons.android.comunic.client.R;
import org.communiquons.android.comunic.client.data.utils.StringsUtils;
import org.communiquons.android.comunic.client.data.utils.Utilities;
/**
* CountDown view
*
* @author Pierre HUBERT
*/
public class CountDownView extends BaseFrameLayoutView {
private static final String TAG = CountDownView.class.getCanonicalName();
private TextView mTimerView;
private int time_end;
private CountDownTimer mTimer;
public CountDownView(@NonNull Context context) {
this(context, null);
}
public CountDownView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
View view = inflate(getContext(), R.layout.view_countdown, this);
mTimerView = view.findViewById(R.id.timer);
}
public int getTime_end() {
return time_end;
}
public void setTime_end(final int time_end) {
this.time_end = time_end;
final int remaining = time_end - Utilities.time();
if(mTimer != null)
mTimer.cancel();
if(remaining < 1){
mTimerView.setText(timeToString(0));
return;
}
mTimer = new CountDownTimer(remaining*1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mTimerView.setText(timeToString(time_end - Utilities.time()));
}
@Override
public void onFinish() {
mTimerView.setText(timeToString(0));
}
}.start();
}
/**
* Parse an amount of time into a string
*
* @param time The time to parse
* @return Result of operation
*/
private String timeToString(int time){
int days = (int)Math.floor(time / 86400);
int remaining_time = time % 86400;
int hours = (int)Math.floor(remaining_time / 3600);
remaining_time %= 3600;
int minutes = (int)Math.floor(remaining_time / 60);
int seconds = remaining_time % 60;
Log.v(TAG, days + "d " + hours + ":" + minutes + ":" + seconds);
return StringsUtils.EnsureZerosInNumberString(days, 2) + "d "
+ StringsUtils.EnsureZerosInNumberString(hours, 2) + ":"
+ StringsUtils.EnsureZerosInNumberString(minutes, 2) + ":"
+ StringsUtils.EnsureZerosInNumberString(seconds, 2);
}
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
tools:text="01/01/03 05:07:05"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>