Left over files from previous comit :/
This commit is contained in:
@@ -8,7 +8,9 @@ import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.aldo.apps.ochecompanion.ui.PlayerStatsView;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View;
|
||||
@@ -88,6 +90,11 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
*/
|
||||
private MaterialButton mSaveButton;
|
||||
|
||||
/**
|
||||
* Button to show the player stats.
|
||||
*/
|
||||
private MaterialButton mShowStatsButton;
|
||||
|
||||
/**
|
||||
* Button to delete a players profile from the database.
|
||||
*/
|
||||
@@ -105,7 +112,17 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
*/
|
||||
private CropOverlayView mCropOverlay;
|
||||
|
||||
/**
|
||||
* View displaying the player's statistics.
|
||||
*/
|
||||
private PlayerStatsView mPlayerStatsView;
|
||||
|
||||
// ========== Data State ==========
|
||||
|
||||
/**
|
||||
* Boolean flag indicating whether the stats view is shown.
|
||||
*/
|
||||
private boolean mIsStatsViewShown = false;
|
||||
|
||||
/**
|
||||
* Absolute file path to the saved profile picture in internal storage.
|
||||
@@ -201,6 +218,17 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
Log.d(TAG, "onBackPressed() called with StatsView shown = [" + mIsStatsViewShown + "]");
|
||||
if (mIsStatsViewShown) {
|
||||
mPlayerStatsView.setVisibility(View.GONE);
|
||||
mIsStatsViewShown = false;
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all UI component references and sets up click listeners.
|
||||
*/
|
||||
@@ -213,6 +241,8 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
mProfilePictureView = findViewById(R.id.ivAddPlayerProfile);
|
||||
mUserNameInput = findViewById(R.id.etUsername);
|
||||
mTitleView = findViewById(R.id.tvTitle);
|
||||
mShowStatsButton = findViewById(R.id.btnShowStats);
|
||||
mPlayerStatsView = findViewById(R.id.player_stats_view);
|
||||
mSaveButton = findViewById(R.id.btnSavePlayer);
|
||||
mBtnDelete = findViewById(R.id.btnDeletePlayer);
|
||||
|
||||
@@ -452,6 +482,7 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
new Thread(() -> {
|
||||
// Query the database for the player (background thread)
|
||||
mExistingPlayer = AppDatabase.getDatabase(this).playerDao().getPlayerById(mExistingPlayerId);
|
||||
final Statistics statistics = AppDatabase.getDatabase(this).statisticsDao().getStatisticsForPlayer(mExistingPlayerId);
|
||||
|
||||
// Update UI on the main thread
|
||||
runOnUiThread(() -> {
|
||||
@@ -463,6 +494,14 @@ public class AddPlayerActivity extends BaseActivity {
|
||||
mTitleView.setText(R.string.txt_update_profile_header);
|
||||
mSaveButton.setText(R.string.txt_update_profile_username_save);
|
||||
if (mBtnDelete != null) mBtnDelete.setVisibility(View.VISIBLE);
|
||||
if (mShowStatsButton != null) mShowStatsButton.setVisibility(View.VISIBLE);
|
||||
mShowStatsButton.setOnClickListener(v -> {
|
||||
mPlayerStatsView.setVisibility(View.VISIBLE);
|
||||
mIsStatsViewShown = true;
|
||||
});
|
||||
if (statistics != null && mPlayerStatsView != null) {
|
||||
mPlayerStatsView.bind(mExistingPlayer, statistics);
|
||||
}
|
||||
|
||||
// Load existing profile picture if available
|
||||
if (mExistingPlayer.profilePictureUri != null) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.aldo.apps.ochecompanion;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.aldo.apps.ochecompanion;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.aldo.apps.ochecompanion.database.AppDatabase;
|
||||
import com.aldo.apps.ochecompanion.database.DatabaseHelper;
|
||||
import com.aldo.apps.ochecompanion.database.objects.Player;
|
||||
import com.aldo.apps.ochecompanion.database.objects.Match;
|
||||
import com.aldo.apps.ochecompanion.ui.MatchRecapView;
|
||||
@@ -55,6 +56,13 @@ public class MainMenuActivity extends BaseActivity {
|
||||
*/
|
||||
private SharedPreferences mSettingsPref;
|
||||
|
||||
/**
|
||||
* Centralized database helper that manages all database operations with proper synchronization.
|
||||
*/
|
||||
private DatabaseHelper mDatabaseHelper;
|
||||
|
||||
private Match mOngoingMatch;
|
||||
|
||||
/**
|
||||
* Initializes the activity: enables edge-to-edge display, configures window insets,
|
||||
* and sets up the match recap view with test data click listener.
|
||||
@@ -69,6 +77,7 @@ public class MainMenuActivity extends BaseActivity {
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_main);
|
||||
mSettingsPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
mDatabaseHelper = DatabaseHelper.getInstance(this);
|
||||
|
||||
// Configure window insets to properly handle system bars (status bar, navigation bar)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||
@@ -84,12 +93,22 @@ public class MainMenuActivity extends BaseActivity {
|
||||
quickStartBtn.setOnClickListener(v -> quickStart());
|
||||
findViewById(R.id.btnSettings).setOnClickListener(v -> launchSettings());
|
||||
|
||||
final List<Match> ongoingMatches = (List<Match>) mDatabaseHelper.getOngoingMatches();
|
||||
if (ongoingMatches != null && !ongoingMatches.isEmpty()) {
|
||||
mOngoingMatch = ongoingMatches.get(0);
|
||||
}
|
||||
if (mOngoingMatch != null) {
|
||||
Log.d(TAG, "onCreate: Found ongoing match [" + mOngoingMatch + "]");
|
||||
quickStartBtn.setSubText("Continue match with " + mOngoingMatch.gameMode + " score");
|
||||
}
|
||||
|
||||
// Set up match recap view with test data functionality
|
||||
mMatchRecap = findViewById(R.id.match_recap);
|
||||
mMatchRecap.setOnClickListener(v -> {
|
||||
// Cycle through test data scenarios on each click
|
||||
applyTestData(mTestCounter);
|
||||
mTestCounter++;
|
||||
new Thread(() -> mDatabaseHelper.printAllMatches()).start();
|
||||
});
|
||||
|
||||
findViewById(R.id.title_view).setOnClickListener(v -> startActivity(new Intent(MainMenuActivity.this, TestActivity.class)));
|
||||
@@ -115,19 +134,26 @@ public class MainMenuActivity extends BaseActivity {
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a quick-start 501 game with two test players.
|
||||
* Creates test players "Test1" and "Test2" and launches GameActivity.
|
||||
* Test players are not persisted to the database.
|
||||
/**game.
|
||||
* Checks for any ongoing matches and resumes them if found,
|
||||
* otherwise starts a new game with the default score.
|
||||
*/
|
||||
private void quickStart() {
|
||||
final Player playerOne = new Player(DartsConstants.TEST_PLAYER_1, null);
|
||||
final Player playerTwo = new Player(DartsConstants.TEST_PLAYER_2, null);
|
||||
final ArrayList<Player> players = new ArrayList<>();
|
||||
players.add(playerOne);
|
||||
players.add(playerTwo);
|
||||
|
||||
GameActivity.start(MainMenuActivity.this, players, DartsConstants.DEFAULT_GAME_SCORE);
|
||||
// Check for ongoing matches in background thread
|
||||
int startingScore = DartsConstants.DEFAULT_GAME_SCORE;
|
||||
int matchId = -1;
|
||||
if (mOngoingMatch != null) {
|
||||
try {
|
||||
Log.d(TAG, "quickStart: Parsing [" + mOngoingMatch + "]");
|
||||
startingScore = Integer.parseInt(mOngoingMatch.gameMode);
|
||||
matchId = mOngoingMatch.id;
|
||||
} catch (final NumberFormatException exception) {
|
||||
Log.e(TAG, "quickStart: Could not extract score from [" + mOngoingMatch + "], use default");
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "quickStart: Starting match with StartingScore = [" + startingScore
|
||||
+ "] and matchId = [" + matchId + "]");
|
||||
GameActivity.start(MainMenuActivity.this, startingScore, matchId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,19 +177,10 @@ public class MainMenuActivity extends BaseActivity {
|
||||
final Intent intent = new Intent(MainMenuActivity.this, AddPlayerActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
// Database operations must be run on a background thread to keep the UI responsive.
|
||||
new Thread(() -> {
|
||||
// Access the singleton database and query all players
|
||||
final List<Player> allPlayers = AppDatabase.getDatabase(getApplicationContext())
|
||||
.playerDao()
|
||||
.getAllPlayers();
|
||||
final List<Player> allPlayers = (List<Player>) mDatabaseHelper.getAllPlayers();
|
||||
runOnUiThread(() -> adapter.updatePlayers(allPlayers));
|
||||
|
||||
// Post-database query UI updates must happen back on the main (UI) thread
|
||||
runOnUiThread(() -> {
|
||||
// Update the adapter with the retrieved player data
|
||||
adapter.updatePlayers(allPlayers);
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -171,14 +188,12 @@ public class MainMenuActivity extends BaseActivity {
|
||||
* Applies the last completed match from the database to the match recap view.
|
||||
*/
|
||||
private void applyLastMatch() {
|
||||
// Database operations must be run on a background thread to keep the UI responsive.
|
||||
new Thread(() -> {
|
||||
final Match lastMatch = AppDatabase.getDatabase(getApplicationContext())
|
||||
.matchDao()
|
||||
.getLastCompletedMatch();
|
||||
|
||||
// Post-database query UI updates must happen back on the main (UI) thread
|
||||
runOnUiThread(() -> mMatchRecap.setMatch(lastMatch));
|
||||
final Match lastCompleted = mDatabaseHelper.getLastCompletedMatch();
|
||||
if (lastCompleted != null) {
|
||||
Log.d(TAG, "applyLastMatch: Applying last completed match [" + lastCompleted + "]");
|
||||
runOnUiThread(() -> mMatchRecap.setMatch(lastCompleted));
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.aldo.apps.ochecompanion;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.aldo.apps.ochecompanion.database;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import com.aldo.apps.ochecompanion.database.objects.Match;
|
||||
import com.aldo.apps.ochecompanion.database.objects.Player;
|
||||
import com.aldo.apps.ochecompanion.database.objects.Statistics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -306,6 +308,104 @@ public class DatabaseHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public long createNewMatch(final String gameMode, final List<Player> players) {
|
||||
final Match match = new Match(System.currentTimeMillis(), gameMode, players.size(), null, Match.MatchState.ONGOING);
|
||||
try {
|
||||
return mExecutor.submit(() -> {
|
||||
try {
|
||||
return mDatabase.matchDao().insert(match);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "createNewMatch: Failed to insert match", e);
|
||||
return -1L;
|
||||
}
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "createNewMatch: Failed to submit task", e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing match in the database.
|
||||
*
|
||||
* @param match The Match entity to update
|
||||
*/
|
||||
public void updateMatch(final Match match) {
|
||||
mExecutor.execute(() -> {
|
||||
try {
|
||||
mDatabase.matchDao().update(match);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "updateMatch: Failed to update match", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<?> getOngoingMatches() {
|
||||
try {
|
||||
return mExecutor.submit(() -> {
|
||||
try {
|
||||
return mDatabase.matchDao().getOngoingMatches();
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "getOngoingMatch() failed");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getOngoingMatch: Failed fetching ongoing matches");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public void printAllMatches() {
|
||||
Log.d(TAG, "printAllMatches() called");
|
||||
try {
|
||||
mExecutor.submit(() -> {
|
||||
final List<Match> allMatches = mDatabase.matchDao().getAllMatches();
|
||||
if (allMatches != null && !allMatches.isEmpty()) {
|
||||
for (final Match match : allMatches) {
|
||||
Log.d(TAG, "printAllMatches: Match = [" + match + "]");
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "printAllMatches: allMatches = [" + allMatches + "]");
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "printAllMatches: Failed to submit task", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Match getLastCompletedMatch() {
|
||||
try {
|
||||
return mExecutor.submit(() -> {
|
||||
try {
|
||||
return mDatabase.matchDao().getLastCompletedMatch();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getLastCompletedMatch: Failed to retrieve last completed match", e);
|
||||
return null;
|
||||
}
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getLastCompletedMatch: Failed to submit task", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Match getMatchById(final int matchId) {
|
||||
try {
|
||||
return mExecutor.submit(() -> {
|
||||
try {
|
||||
return mDatabase.matchDao().getMatchById(matchId);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getMatchById: Failed to retrieve match", e);
|
||||
return null;
|
||||
}
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getMatchById: Failed to submit task", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves statistics for a specific player synchronously.
|
||||
* Blocks until the operation completes to ensure consistency with any pending writes.
|
||||
|
||||
@@ -20,7 +20,16 @@ public interface MatchDao {
|
||||
* @param match The Match entity to persist
|
||||
*/
|
||||
@Insert
|
||||
void insert(final Match match);
|
||||
long insert(final Match match);
|
||||
|
||||
/**
|
||||
* Updates an existing match record in the database.
|
||||
* Must be called on a background thread.
|
||||
*
|
||||
* @param match The Match entity to update
|
||||
*/
|
||||
@androidx.room.Update
|
||||
void update(final Match match);
|
||||
|
||||
/**
|
||||
* Retrieves all match records ordered by most recent first.
|
||||
@@ -40,6 +49,9 @@ public interface MatchDao {
|
||||
@Query("SELECT * FROM matches ORDER BY timestamp DESC LIMIT 1")
|
||||
Match getLastMatch();
|
||||
|
||||
@Query("SELECT * FROM matches WHERE id = :matchId")
|
||||
Match getMatchById(final int matchId);
|
||||
|
||||
/**
|
||||
* Retrieves the most recently completed match.
|
||||
* Must be called on a background thread.
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.aldo.apps.ochecompanion.database.objects;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import com.aldo.apps.ochecompanion.utils.DartsConstants;
|
||||
import com.aldo.apps.ochecompanion.utils.MatchProgress;
|
||||
import com.aldo.apps.ochecompanion.utils.converters.MatchProgressConverter;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -27,6 +34,8 @@ import java.util.Map;
|
||||
@Entity(tableName = "matches")
|
||||
public class Match implements Serializable {
|
||||
|
||||
private static final String TAG = "Match";
|
||||
|
||||
/**
|
||||
* Represents the current state of a match.
|
||||
*/
|
||||
@@ -157,14 +166,9 @@ public class Match implements Serializable {
|
||||
* @return The username of the player, or "Unknown" if unavailable
|
||||
*/
|
||||
public String getPlayerNameByPosition(final int position) {
|
||||
try {
|
||||
final JSONArray participants = new JSONArray(participantData);
|
||||
if (position >= 0 && position < participants.length()) {
|
||||
final JSONObject participant = participants.getJSONObject(position);
|
||||
return participant.optString("username", "Unknown");
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Return default if JSON parsing fails
|
||||
final MatchProgress progress = MatchProgressConverter.fromString(participantData);
|
||||
if (progress != null && progress.players != null && position < progress.players.size()) {
|
||||
return progress.players.get(position).name;
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -176,14 +180,14 @@ public class Match implements Serializable {
|
||||
* @return The career average, or 0.0 if unavailable
|
||||
*/
|
||||
public double getPlayerAverageByPosition(final int position) {
|
||||
try {
|
||||
final JSONArray participants = new JSONArray(participantData);
|
||||
if (position >= 0 && position < participants.length()) {
|
||||
final JSONObject participant = participants.getJSONObject(position);
|
||||
return participant.optDouble("careerAverage", 0.0);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Return default if JSON parsing fails
|
||||
final MatchProgress progress = MatchProgressConverter.fromString(participantData);
|
||||
if (progress != null && progress.players != null && position < progress.players.size()) {
|
||||
final int dartsThrown = progress.players.get(position).dartsThrown;
|
||||
final int startingScore = progress.startingScore;
|
||||
final int scoreLeft = progress.players.get(position).remainingScore;
|
||||
final int scoredPoints = (scoreLeft - startingScore) * -1;
|
||||
|
||||
return (double) scoredPoints / dartsThrown * 3;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
@@ -195,14 +199,9 @@ public class Match implements Serializable {
|
||||
* @return The match score, or 0 if unavailable
|
||||
*/
|
||||
public int getPlayerScoreByPosition(final int position) {
|
||||
try {
|
||||
final JSONArray participants = new JSONArray(participantData);
|
||||
if (position >= 0 && position < participants.length()) {
|
||||
final JSONObject participant = participants.getJSONObject(position);
|
||||
return participant.optInt("score", 0);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Return default if JSON parsing fails
|
||||
final MatchProgress progress = MatchProgressConverter.fromString(participantData);
|
||||
if (progress != null && progress.players != null && position < progress.players.size()) {
|
||||
return progress.players.get(position).remainingScore;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -360,4 +359,16 @@ public class Match implements Serializable {
|
||||
public boolean isCanceled() {
|
||||
return this.state == MatchState.CANCELED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Match{" +
|
||||
"id=" + id +
|
||||
", timestamp=" + timestamp +
|
||||
", gameMode='" + gameMode + '\'' +
|
||||
", playerCount=" + playerCount +
|
||||
", participantData='" + participantData + '\'' +
|
||||
", state=" + state +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.aldo.apps.ochecompanion.database.objects;
|
||||
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Entity;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.aldo.apps.ochecompanion.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aldo.apps.ochecompanion.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
@@ -19,6 +20,11 @@ import com.aldo.apps.ochecompanion.ui.adapter.MainMenuGroupMatchAdapter;
|
||||
*/
|
||||
public class MatchRecapView extends FrameLayout {
|
||||
|
||||
/**
|
||||
* Tag for debugging purposes.
|
||||
*/
|
||||
private static final String TAG = "MatchRecapView";
|
||||
|
||||
/** View container for empty state (no match history). */
|
||||
private View mStateEmpty;
|
||||
|
||||
@@ -75,6 +81,7 @@ public class MatchRecapView extends FrameLayout {
|
||||
|
||||
/** Binds match and updates display (empty, 1v1, or group state). */
|
||||
public void setMatch(@Nullable final Match match) {
|
||||
Log.d(TAG, "setMatch() called with: match = [" + match + "]");
|
||||
if (match == null) {
|
||||
updateVisibility(mStateEmpty);
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.aldo.apps.ochecompanion.ui.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -5,7 +5,7 @@ import static com.aldo.apps.ochecompanion.AddPlayerActivity.EXTRA_PLAYER_ID;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -1,4 +1,153 @@
|
||||
package com.aldo.apps.ochecompanion.utils;
|
||||
|
||||
|
||||
/**
|
||||
* Class {@link Log} is a wrapper class around android.util.Log.
|
||||
*
|
||||
* The sole purpose of this class is to have a single TAG by which all log output from the
|
||||
* CoreSyncService can later on be found in the log. The classes using this logging class may
|
||||
* still define their custom tag. This will ease identifying OcheCompanion logs.
|
||||
*/
|
||||
public class Log {
|
||||
/**
|
||||
* The TAG that identifies OcheCompanion messages in the log.
|
||||
*/
|
||||
private static final String TAG = "OcheCompanion_Log";
|
||||
|
||||
/**
|
||||
* Send a debug message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void d(final String tag, final String msg) {
|
||||
android.util.Log.d(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a debug message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void d(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.d(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a info message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void i(final String tag, final String msg) {
|
||||
android.util.Log.i(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a info message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void i(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.i(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a error message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void e(final String tag, final String msg) {
|
||||
android.util.Log.e(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a error message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void e(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.e(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a verbose message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void v(final String tag, final String msg) {
|
||||
android.util.Log.v(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a verbose message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void v(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.v(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a warning message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void w(final String tag, final String msg) {
|
||||
android.util.Log.w(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a warning message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void w(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.w(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a "what a terrible failure" message and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void wtf(final String tag, final String msg, final Throwable throwable) {
|
||||
android.util.Log.wtf(TAG, String.format("(%s): %s", tag, msg), throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a "what a terrible failure" message.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param msg the message to be logged
|
||||
*/
|
||||
public static void wtf(final String tag, final String msg) {
|
||||
android.util.Log.wtf(TAG, String.format("(%s): %s", tag, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a "what a terrible failure" tag and print the exception.
|
||||
*
|
||||
* @param tag string used to identify the source of a log message
|
||||
* @param throwable the exception to be logged
|
||||
*/
|
||||
public static void wtf(final String tag, final Throwable throwable) {
|
||||
android.util.Log.wtf(TAG, String.format("(%s):", tag), throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,33 @@
|
||||
package com.aldo.apps.ochecompanion.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MatchProgress: A serializable snapshot of an ongoing X01 session.
|
||||
* Stores the current scores, darts thrown, and active player index
|
||||
* to allow resuming matches from the database.
|
||||
*/
|
||||
public class MatchProgress {
|
||||
}
|
||||
public int activePlayerIndex;
|
||||
public int startingScore;
|
||||
public List<PlayerStateSnapshot> players;
|
||||
|
||||
/**
|
||||
* Represents the state of an individual player at a point in time.
|
||||
*/
|
||||
public static class PlayerStateSnapshot {
|
||||
public long playerId; // 0 for guests
|
||||
public String name;
|
||||
public int remainingScore;
|
||||
public int dartsThrown;
|
||||
|
||||
public PlayerStateSnapshot() {}
|
||||
|
||||
public PlayerStateSnapshot(final long playerId, final String name, final int remainingScore, final int dartsThrown) {
|
||||
this.playerId = playerId;
|
||||
this.name = name;
|
||||
this.remainingScore = remainingScore;
|
||||
this.dartsThrown = dartsThrown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.SoundPool;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import com.aldo.apps.ochecompanion.utils.Log;
|
||||
|
||||
import com.aldo.apps.ochecompanion.R;
|
||||
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
package com.aldo.apps.ochecompanion.utils.converters;
|
||||
|
||||
import androidx.room.TypeConverter;
|
||||
|
||||
import com.aldo.apps.ochecompanion.utils.MatchProgress;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* MatchProgressConverter: Handles serialization of complex match states
|
||||
* into JSON strings for storage in the Room 'matches' table.
|
||||
*/
|
||||
public class MatchProgressConverter {
|
||||
}
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
@TypeConverter
|
||||
public static MatchProgress fromString(String value) {
|
||||
if (value == null || value.isEmpty()) return null;
|
||||
return gson.fromJson(value, MatchProgress.class);
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static String fromProgress(MatchProgress progress) {
|
||||
if (progress == null) return null;
|
||||
return gson.toJson(progress);
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,16 @@
|
||||
android:textColor="@color/text_primary" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnShowStats"
|
||||
style="@style/Widget.Oche_Button_Primary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="@string/txt_create_profile_show_stats"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSavePlayer"
|
||||
style="@style/Widget.Oche_Button_Primary"
|
||||
@@ -120,4 +130,10 @@
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.aldo.apps.ochecompanion.ui.PlayerStatsView
|
||||
android:id="@+id/player_stats_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -17,6 +17,7 @@
|
||||
<string name="txt_create_profile_header">Create Profile</string>
|
||||
<string name="txt_create_profile_username_hint">Add your username</string>
|
||||
<string name="txt_create_profile_username_save">Save to Squad</string>
|
||||
<string name="txt_create_profile_show_stats">Show Stats</string>
|
||||
<string name="txt_update_profile_header">Update Profile</string>
|
||||
<string name="txt_update_profile_username_save">Update Squad</string>
|
||||
<string name="txt_cancel_crop">Cancel</string>
|
||||
|
||||
Reference in New Issue
Block a user