Skip to content

Commit

Permalink
Merge pull request #7 from SDIDSA/online
Browse files Browse the repository at this point in the history
Online
  • Loading branch information
SDIDSA authored Jul 23, 2023
2 parents d309add + b52bdb5 commit 6365965
Show file tree
Hide file tree
Showing 46 changed files with 3,082 additions and 388 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ android {
applicationId "org.luke.diminou"
minSdk 24
targetSdk 34
versionCode 1
versionName "0.1.1"
versionCode 3
versionName "0.1.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
Expand Down
141 changes: 120 additions & 21 deletions app/src/main/java/org/luke/diminou/abs/App.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package org.luke.diminou.abs;

import android.Manifest;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
Expand All @@ -22,6 +28,9 @@
import androidx.annotation.NonNull;
import androidx.annotation.RawRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
Expand All @@ -30,7 +39,6 @@

import com.google.android.gms.auth.api.signin.GoogleSignInAccount;

import org.json.JSONObject;
import org.luke.diminou.R;
import org.luke.diminou.abs.animation.base.Animation;
import org.luke.diminou.abs.animation.base.ValueAnimation;
Expand All @@ -49,6 +57,7 @@
import org.luke.diminou.abs.locale.Locale;
import org.luke.diminou.abs.net.SocketConnection;
import org.luke.diminou.abs.style.Style;
import org.luke.diminou.abs.utils.NotificationAction;
import org.luke.diminou.abs.utils.Permissions;
import org.luke.diminou.abs.utils.Platform;
import org.luke.diminou.abs.utils.Store;
Expand All @@ -57,8 +66,7 @@
import org.luke.diminou.app.account.google.GoogleAccountHandler;
import org.luke.diminou.app.account.google.GoogleOauthContract;
import org.luke.diminou.app.pages.SplashScreen;
import org.luke.diminou.app.pages.game.player.Player;
import org.luke.diminou.app.pages.home.online.global.RoomId;
import org.luke.diminou.app.pages.game.offline.player.OfflinePlayer;
import org.luke.diminou.app.pages.settings.FourMode;
import org.luke.diminou.app.pages.settings.Timer;
import org.luke.diminou.data.beans.Room;
Expand All @@ -70,6 +78,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

Expand Down Expand Up @@ -167,6 +176,7 @@ protected void onCreate(Bundle savedInstanceState) {
Font.DEFAULT = new Font(nv.getFontFamily());
}
});
createNotificationChannel();
}, "app_init_thread").start();
}

Expand All @@ -175,15 +185,15 @@ public void googleSignIn(ObjectConsumer<GoogleSignInAccount> onAcc, Runnable onF
googleSignIn.launch("google sign in");
}

public void requirePermissions(Runnable onGranted, String...permissions) {
public void requirePermissions(Runnable onGranted, String... permissions) {
if (isGranted(permissions)) {
onGranted.run();
} else {
requestPermission(onGranted, permissions);
}
}

private void requestPermission(Runnable onGranted, String...permissions) {
private void requestPermission(Runnable onGranted, String... permissions) {
int code = Permissions.permissionRequestCode();
onPermission.put(code, onGranted);
requestPermissions(permissions, code);
Expand Down Expand Up @@ -213,7 +223,7 @@ private boolean isGranted(String permission) {
}

public void pickImage(ObjectConsumer<Media> onRes) {
if(mediaPicker == null) {
if (mediaPicker == null) {
mediaPicker = new MediaPickerOverlay(this);
}
mediaPicker.setOnMedia(onRes);
Expand All @@ -234,6 +244,7 @@ public Bitmap getBitmapFromView(View view) {
}

private boolean paused = false;

@Override
protected void onPause() {
super.onPause();
Expand All @@ -249,21 +260,33 @@ public boolean isPaused() {
protected void onResume() {
super.onResume();
paused = false;
if(Store.getAmbient().equals("off")) muteAmbient();
if (Store.getAmbient().equals("off")) muteAmbient();
else unmuteAmbient();

int id = getIntent().getIntExtra("id", -1);
Runnable action = id == -1 ? null : onNotification.get(id);
if(action != null) {
action.run();
}
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}

public void startAmbient() {
MediaPlayer mp = getSound(R.raw.ambient);
mp.setLooping(true);
mp.start();
if(Store.getAmbient().equals("off")) muteAmbient();
if (Store.getAmbient().equals("off")) muteAmbient();
else unmuteAmbient();
}

public void applyAmbient(boolean b) {
Store.setAmbient(b ? "on" : "off", null);
if(b) unmuteAmbient();
if (b) unmuteAmbient();
else muteAmbient();
}

Expand All @@ -277,7 +300,7 @@ public void unmuteAmbient() {

private synchronized MediaPlayer getSound(@RawRes int res) {
MediaPlayer mp = sounds.get(res);
if(mp == null) {
if (mp == null) {
mp = MediaPlayer.create(this, res);
sounds.put(res, mp);
}
Expand All @@ -286,20 +309,20 @@ private synchronized MediaPlayer getSound(@RawRes int res) {
}

public synchronized void playMenuSound(@RawRes int res) {
if(Store.getMenuSounds().equals("on")) playSound(res);
if (Store.getMenuSounds().equals("on")) playSound(res);
}

public synchronized void playGameSound(@RawRes int res) {
if(Store.getGameSounds().equals("on")) playSound(res);
if (Store.getGameSounds().equals("on")) playSound(res);
}

private synchronized void playSound(@RawRes int res) {
if(paused) return;
if (paused) return;
MediaPlayer mp = getSound(res);
try {
mp.seekTo(0);
mp.start();
}catch(Exception x) {
} catch (Exception x) {
sounds.remove(res);
playSound(res);
}
Expand Down Expand Up @@ -329,11 +352,11 @@ public void loadPage(Class<? extends Page> pageType, Runnable post) {
AtomicReference<Page> page = new AtomicReference<>();
Page old = loaded;
if (old != null) {
if(!(old instanceof SplashScreen))
if (!(old instanceof SplashScreen))
playMenuSound(R.raw.page);
running = new ParallelAnimation(500).addAnimation(new AlphaAnimation(old, 0)).addAnimation(new TranslateYAnimation(old, ViewUtils.dipToPx(-30, this))).setInterpolator(Interpolator.EASE_OUT).setOnFinished(() -> {
root.removeView(old);
old.destroy();
old.destroy(loaded);
if (post != null) post.run();
});
running.start();
Expand Down Expand Up @@ -374,7 +397,7 @@ public void removeLoaded() {
if (loaded == null) return;

root.removeView(loaded);
loaded.destroy();
loaded.destroy(null);
loaded = null;
}

Expand All @@ -393,6 +416,73 @@ public void addOverlay(Overlay overlay) {
loadedOverlay.add(0, overlay);
}

private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel =
new NotificationChannel("main", "diminou", importance);
channel.enableVibration(true);
channel.setDescription("main channel to notify users");
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}

private final HashMap<Integer, Runnable> onNotification = new HashMap<>();

public void notify(String head, String body, Runnable onOpen, NotificationAction...actions) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}

int notificationId = new Random().nextInt(Integer.MAX_VALUE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "main")
.setSmallIcon(R.drawable.icon)
.setContentTitle(head)
.setContentText(body)
.setDefaults(NotificationCompat.DEFAULT_SOUND | NotificationCompat.DEFAULT_VIBRATE) //Important for heads-up notification
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(createIntent(onOpen))
.setAutoCancel(true);

for(NotificationAction action : actions) {
builder.addAction(new NotificationCompat.Action(
action.getIcon(),
action.getText(),
createIntent(() -> {
notificationManager.cancel(notificationId);
action.getAction().run();
})
));
}

Notification notification = builder.build();

notificationManager.notify(notificationId, notification);
}

private PendingIntent createIntent(Runnable action) {
Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.setPackage(null);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

int id = new Random().nextInt(Integer.MAX_VALUE);
intent.putExtra("id", id);

onNotification.put(id, action);

return PendingIntent.getActivity(this, id,
intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
}

public void toast(long duration, View... views) {
VBox toast = new VBox(this);
toast.setHorizontalGravity(Gravity.CENTER_HORIZONTAL);
Expand Down Expand Up @@ -611,12 +701,21 @@ public Timer getTimer() {
return Timer.byText(getString("timer"));
}

public List<Player> getPlayers() {
public List<OfflinePlayer> getPlayers() {
return getTypedData("players");
}

public ConcurrentHashMap<Player, Integer> getScore() {
ConcurrentHashMap<Player, Integer> score = getTypedData("score");
public ConcurrentHashMap<OfflinePlayer, Integer> getOfflineScore() {
ConcurrentHashMap<OfflinePlayer, Integer> score = getTypedData("offline_score");
if(score == null) {
score = new ConcurrentHashMap<>();
putData("score", score);
}
return score;
}

public ConcurrentHashMap<Integer, Integer> getScore() {
ConcurrentHashMap<Integer, Integer> score = getTypedData("score");
if(score == null) {
score = new ConcurrentHashMap<>();
putData("score", score);
Expand All @@ -632,7 +731,7 @@ public SocketConnection getSocket() {
return getTypedData("socket");
}

public Player getWinner() {
public OfflinePlayer getWinner() {
return getTypedData("winner");
}

Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/org/luke/diminou/abs/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,18 @@ public static class Session {

public static final String SWAP = PREFIX + "swap";

public static final String BEGIN = PREFIX + "begin";

private Session() {

}
}

public static class Game {
private static final String PREFIX = BASE + "game/";

public static final String DEAL = PREFIX + "deal";

public static final String PLAY = PREFIX + "play";
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/org/luke/diminou/abs/api/AuthRoute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.luke.diminou.abs.api;

import android.util.Log;

import org.json.JSONObject;
import org.luke.diminou.abs.api.json.Param;
import org.luke.diminou.abs.api.multipart.Part;
import org.luke.diminou.abs.utils.functional.ObjectConsumer;
import org.luke.diminou.data.SessionManager;

public class AuthRoute {

static void call(String path, String action, ObjectConsumer<JSONObject> onResult, Param... params) {
String session = SessionManager.getSession();
Log.i("session", session);
API.asyncJsonPost(path, action, onResult, session, params);
}

static void callMulti(String path, String action, ObjectConsumer<JSONObject> onResult, Part... parts) {
API.asyncMultiPost(path, action, onResult, SessionManager.getSession(), parts);
}
}
19 changes: 19 additions & 0 deletions app/src/main/java/org/luke/diminou/abs/api/GameRoute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.luke.diminou.abs.api;

import org.json.JSONObject;
import org.luke.diminou.abs.api.json.Param;
import org.luke.diminou.abs.utils.functional.ObjectConsumer;
import org.luke.diminou.app.pages.game.piece.Move;

public class GameRoute extends AuthRoute {
public static void deal(String roomId, ObjectConsumer<JSONObject> onResult) {
call(API.Game.DEAL, "request deal from server", onResult,
new Param("room_id", roomId));
}

public static void play(String roomId, Move move, ObjectConsumer<JSONObject> onResult) {
call(API.Game.PLAY, "play move", onResult,
new Param("room_id", roomId),
new Param("move", move.serialize()));
}
}
Loading

0 comments on commit 6365965

Please sign in to comment.