Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
[![](https://img.shields.io/docker/build/thnuiwelr/mipush.svg)](https://hub.docker.com/r/thnuiwelr/mipush/)
[![](https://img.shields.io/docker/pulls/thnuiwelr/mipush.svg)](https://hub.docker.com/r/thnuiwelr/mipush/)
[![](https://img.shields.io/microbadger/image-size/thnuiwelr/mipush.svg)](https://hub.docker.com/r/thnuiwelr/mipush/)
[![Build Status](https://travis-ci.org/Trumeet/MiPushTester.svg?branch=master)](https://travis-ci.org/Trumeet/MiPushTester)
<p align="center">
<a href="https://hub.docker.com/r/thnuiwelr/mipush/"><img src="https://img.shields.io/docker/build/thnuiwelr/mipush.svg" alt="" /></a>
<a href="https://hub.docker.com/r/thnuiwelr/mipush/"><img src="https://img.shields.io/docker/pulls/thnuiwelr/mipush.svg" alt="" /></a>
<a href="https://hub.docker.com/r/thnuiwelr/mipush/"><img src="https://img.shields.io/microbadger/image-size/thnuiwelr/mipush.svg" alt="" /></a>
<a href="https://travis-ci.org/Trumeet/MiPushTester"><img src="https://travis-ci.org/Trumeet/MiPushTester.svg?branch=master" alt="Build Status" /></a>
<a href="https://github.com/Trumeet/MiPushTester/releases"><img src="https://img.shields.io/github/release-pre/Trumeet/MiPushTester.svg" alt="Latest release" /></a>
<a href="https://github.com/Trumeet/MiPushTester/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Trumeet/MiPushTester.svg" alt="Licenses" /></a>
<a href="https://github.com/Trumeet/MiPushTester/releases"><img src="https://img.shields.io/github/downloads/Trumeet/MiPushTester/total.svg" alt="APK Downloads" /></a>
<a href="https://github.com/Trumeet/MiPushTester/issues"><img src="https://img.shields.io/github/issues/Trumeet/MiPushTester.svg" alt="Open Issues" /></a>
<a href="https://github.com/Trumeet/MiPushTester/pulls"><img src="https://img.shields.io/github/issues-pr/Trumeet/MiPushTester.svg" alt="Open PR" /></a>
<a href="https://github.com/Trumeet/MiPushTester/stargazers"><img src="https://img.shields.io/github/stars/Trumeet/MiPushTester.svg?label=Stars&amp;style=social" alt="Stars" /></a>
<a href="https://status.yuuta.moe/781665748"><img src="https://img.shields.io/uptimerobot/ratio/7/m781665748-4f4339573e81d66d561994f8.svg" alt="Web Status" /></a></p>
</p>

# MiPush Tester (Alpha)

Expand Down
22 changes: 21 additions & 1 deletion app/src/main/java/moe/yuuta/mipushtester/MainFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.Observable;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
import moe.yuuta.mipushtester.api.APIManager;
import moe.yuuta.mipushtester.databinding.FragmentMainBinding;
import moe.yuuta.mipushtester.log.LogUtils;
import moe.yuuta.mipushtester.push.APIManager;
import moe.yuuta.mipushtester.status.RegistrationStatus;
import moe.yuuta.mipushtester.topic.TopicStore;
import moe.yuuta.mipushtester.update.Update;
import retrofit2.Call;
import retrofit2.Callback;
Expand All @@ -66,11 +68,22 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false);
mRegistrationStatus = RegistrationStatus.get(requireContext());
mRegistrationStatus.registered.addOnPropertyChangedCallback(mRestoreSubscriptionListener);
binding.setStatus(mRegistrationStatus);
binding.setUiHandler(this);
return binding.getRoot();
}

private Observable.OnPropertyChangedCallback mRestoreSubscriptionListener =new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (mRegistrationStatus.registered.get()) {
for (String id : TopicStore.create(requireContext()).getSubscribedIds())
MiPushClient.subscribe(requireContext(), id, null);
}
}
};

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Expand Down Expand Up @@ -204,6 +217,13 @@ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflat
@Override
public void onDestroyView() {
if (mGetUpdateCall != null) mGetUpdateCall.cancel();
mRegistrationStatus.registered.removeOnPropertyChangedCallback(mRestoreSubscriptionListener);
super.onDestroyView();
}

@Override
public void handleSubscribeTopic(View v) {
Navigation.findNavController(requireActivity(), R.id.nav_host)
.navigate(R.id.action_mainFragment_to_topicSubscriptionFragment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public interface MainFragmentUIHandler {
void handleToggleRegister (View v);
void handleCreatePush (View v);
void handleReset (View v);
void handleSubscribeTopic (View v);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package moe.yuuta.mipushtester.push;
package moe.yuuta.mipushtester.api;

import com.google.gson.JsonObject;

import java.util.List;

import moe.yuuta.mipushtester.push.PushRequest;
import moe.yuuta.mipushtester.topic.Topic;
import moe.yuuta.mipushtester.update.Update;
import retrofit2.Call;
import retrofit2.http.Body;
Expand All @@ -14,4 +18,7 @@ public interface APIInterface {

@GET("/update")
Call<Update> getUpdate ();

@GET("/test/topic")
Call<List<Topic>> getAvailableTopics ();
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package moe.yuuta.mipushtester.push;
package moe.yuuta.mipushtester.api;

import com.elvishew.xlog.Logger;
import com.elvishew.xlog.XLog;
import com.google.gson.JsonObject;

import java.util.List;
import java.util.Locale;

import androidx.annotation.NonNull;
import moe.yuuta.common.Constants;
import moe.yuuta.mipushtester.BuildConfig;
import moe.yuuta.mipushtester.push.PushRequest;
import moe.yuuta.mipushtester.topic.Topic;
import moe.yuuta.mipushtester.update.Update;
import okhttp3.OkHttpClient;
import okhttp3.Request;
Expand Down Expand Up @@ -51,4 +54,8 @@ public Call<JsonObject> push (@NonNull PushRequest request) {
public Call<Update> getUpdate () {
return apiInterface.getUpdate();
}

public Call<List<Topic>> getAvailableTopics () {
return apiInterface.getAvailableTopics();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.Map;

@SuppressWarnings("unused")
class PushRequest {
public class PushRequest {
@SerializedName("registration_id")
private String registrationId;
@SerializedName("delay_ms")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import moe.yuuta.common.Constants;
import moe.yuuta.mipushtester.BuildConfig;
import moe.yuuta.mipushtester.R;
import moe.yuuta.mipushtester.api.APIManager;
import moe.yuuta.mipushtester.status.RegistrationStatus;
import retrofit2.Response;

Expand Down
47 changes: 47 additions & 0 deletions app/src/main/java/moe/yuuta/mipushtester/topic/Topic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package moe.yuuta.mipushtester.topic;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Topic {
@SerializedName(value = "title")
private String title;
@SerializedName(value = "description")
private String description;
@SerializedName(value = "id")
private String id;
@Expose
private boolean subscribed;

public boolean isSubscribed() {
return subscribed;
}

public void setSubscribed(boolean subscribed) {
this.subscribed = subscribed;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package moe.yuuta.mipushtester.topic;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import moe.yuuta.mipushtester.R;

public class TopicListAdapter extends RecyclerView.Adapter<TopicListAdapter.ViewHolder> {
private List<Topic> mItemList = new ArrayList<>(0);
private Set<String> mSelected = new HashSet<>(3);
private OnSelectedListener mSelectListener;

@FunctionalInterface
interface OnSelectedListener {
void trigger (@NonNull Topic topic, boolean selected);
}

TopicListAdapter (@NonNull OnSelectedListener listener) {
super();
mSelectListener = listener;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_topic, parent, false));
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Topic topic = mItemList.get(position);
if (topic.isSubscribed()) mSelected.add(topic.getId());
else mSelected.remove(topic.getId());
if (mSelected.contains(topic.getId())) {
holder.checkBox.setChecked(true);
} else {
holder.checkBox.setChecked(false);
}
holder.checkBox.setOnClickListener(v -> {
boolean checked = holder.checkBox.isChecked();
mSelectListener.trigger(topic, checked);
if (checked) mSelected.add(topic.getId());
else mSelected.remove(topic.getId());
});
holder.title.setText(topic.getTitle());
holder.description.setText(topic.getDescription());
}

@Override
public int getItemCount() {
return mItemList.size();
}

public Topic getItemAt (int position) {
return mItemList.get(position);
}

public void setItems (@NonNull List<Topic> newList) {
mItemList = newList;
}

static class ViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private TextView description;
private CheckBox checkBox;

ViewHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(android.R.id.text1);
description = itemView.findViewById(android.R.id.text2);
checkBox = itemView.findViewById(R.id.check_subscribe);
}
}
}
68 changes: 68 additions & 0 deletions app/src/main/java/moe/yuuta/mipushtester/topic/TopicStore.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package moe.yuuta.mipushtester.topic;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class TopicStore {
private static TopicStore instance;
private final Object lock = new Object();

public TopicStore getInstance (@Nullable Context context) {
if (instance == null) {
if (context == null)
throw new IllegalArgumentException("Context shouldn't be null if it isn't created yet");
instance = TopicStore.create(context.getApplicationContext());
}
return instance;
}

public static TopicStore create (@NonNull Context context) {
return new TopicStore(context.getSharedPreferences("subscription", Context.MODE_PRIVATE));
}

private final SharedPreferences sharedPreferences;

private TopicStore (@NonNull SharedPreferences sharedPreferences) {
this.sharedPreferences = sharedPreferences;
}

public Set<String> getSubscribedIds () {
synchronized (this.lock) {
return sharedPreferences.getStringSet("subscribed", Collections.emptySet());
}
}

public boolean isSubscribed (@NonNull String id) {
return getSubscribedIds().contains(id);
}

@SuppressLint("ApplySharedPref")
public void subscribe (@NonNull String id) {
synchronized (this.lock) {
Set<String> current = new HashSet<>(getSubscribedIds());
current.add(id);
sharedPreferences.edit()
.putStringSet("subscribed", current)
.commit();
}
}

@SuppressLint("ApplySharedPref")
public void unsubscribe (@NonNull String id) {
synchronized (this.lock) {
Set<String> current = new HashSet<>(getSubscribedIds());
current.remove(id);
sharedPreferences.edit()
.putStringSet("subscribed", current)
.commit();
}
}
}
Loading