From 882c0c4494105b804e40029f0705ea29ea0e7263 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Wed, 19 May 2021 19:49:38 +0200 Subject: [PATCH] Premier commit - Incorporation dans la machinerie git --- .gitignore | 12 + TikTokMurder.iml | 19 + app/.gitignore | 3 + app/app.iml | 132 ++++++ app/build.gradle | 37 ++ app/src/main/AndroidManifest.xml | 27 ++ .../bernard/tiktokmurder/MainActivity.java | 411 ++++++++++++++++++ .../drawable-v24/ic_launcher_foreground.xml | 34 ++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++ .../main/res/drawable/tiktokmurder_icon.xml | 51 +++ .../res/drawable/tiktokmurder_icon_round.xml | 51 +++ app/src/main/res/layout/action_item.xml | 31 ++ app/src/main/res/layout/activity_main.xml | 53 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2963 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4905 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2060 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2783 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4490 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6895 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6387 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10413 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9128 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15132 bytes app/src/main/res/raw/default_murder.yml | 10 + app/src/main/res/values-en/strings.xml | 10 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/strings.xml | 11 + app/src/main/res/values/styles.xml | 11 + build.gradle | 27 ++ gradle.properties | 20 + settings.gradle | 2 + 33 files changed, 1138 insertions(+) create mode 100644 .gitignore create mode 100644 TikTokMurder.iml create mode 100644 app/.gitignore create mode 100644 app/app.iml create mode 100644 app/build.gradle create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/bernard/tiktokmurder/MainActivity.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/tiktokmurder_icon.xml create mode 100644 app/src/main/res/drawable/tiktokmurder_icon_round.xml create mode 100644 app/src/main/res/layout/action_item.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/raw/default_murder.yml create mode 100644 app/src/main/res/values-en/strings.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..850c85b --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.gradle +/local.properties +/.idea +.DS_Store +/build +/captures +.externalNativeBuild +app/build + +gradle/ +gradlew +gradlew.bat diff --git a/TikTokMurder.iml b/TikTokMurder.iml new file mode 100644 index 0000000..4cc8c3d --- /dev/null +++ b/TikTokMurder.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..7b7f1b1 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,3 @@ +/build +/debug +/release diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..00cabfb --- /dev/null +++ b/app/app.iml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..624f7ef --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,37 @@ +apply plugin: 'com.android.application' + +android { + signingConfigs { + debug { + storeFile file('/home/mysaa/Documents/bernard-android.jks') + storePassword 'modulo63' + keyPassword 'néant is all(like 42)' + } + } + compileSdkVersion 29 + buildToolsVersion "29.0.2" + defaultConfig { + applicationId "com.bernard.tiktokmurder" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 2 + versionName "1.1" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'org.yaml:snakeyaml:1.25' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4effb72 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/bernard/tiktokmurder/MainActivity.java b/app/src/main/java/com/bernard/tiktokmurder/MainActivity.java new file mode 100644 index 0000000..13102cf --- /dev/null +++ b/app/src/main/java/com/bernard/tiktokmurder/MainActivity.java @@ -0,0 +1,411 @@ +package com.bernard.tiktokmurder; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import android.Manifest; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.database.DataSetObserver; +import android.os.Bundle; +import android.os.Environment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.Spinner; +import android.widget.SpinnerAdapter; +import android.widget.TextView; +import android.widget.Toast; + +import org.w3c.dom.Text; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MainActivity extends AppCompatActivity { + + + //public static final int DATA_ACCESS_PERMISSION_REQUEST = 44242; + public static DateFormat dateFormat = SimpleDateFormat.getTimeInstance(); + public static final String murderFileName = "murder.yml"; + + private boolean shouldUpdateText = false; + + Button leftArrow,rightArrow; + Spinner playerSelect; + ListView actionList; + + long[][] triggeredTime; + + String[] playerNames; + String[][] playerActions; + Long[][] playerActionBaseTime; + ActionListAdapter[] adapteurs; + + + protected void generateData(){ + Log.i("generateData","Tentative de génération des données"); + Yaml yaml = new Yaml(); + + File murderFile = new File(this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),murderFileName); + Log.i("MurderFile","Recherche du fichier à "+murderFile); + InputStream ist; + List playerNames = new ArrayList<>(); + List commonActions = new ArrayList<>(); + List commonActionsBaseTime = new ArrayList<>(); + Map> playerActions = new HashMap<>(); + Map> playerActionsBaseTime = new HashMap<>(); + try { + if (!murderFile.exists()) { + ist = this.getResources().openRawResource(R.raw.default_murder); + FileOutputStream fos = new FileOutputStream(murderFile); + byte[] data = new byte[ist.available()]; + ist.read(data); + fos.write(data); + fos.close(); + ist.reset(); + }else + ist = new FileInputStream(murderFile); + + Map donnees = yaml.load(ist); + + if(donnees.containsKey("actionsCommunes")){ + Map actionsCommunes = (Map) donnees.get("actionsCommunes"); + for(Map.Entry action : actionsCommunes.entrySet()){ + commonActions.add(action.getKey()); + commonActionsBaseTime.add(parseTime(action.getValue())); + } + } + if(donnees.containsKey("joueurs")){ + Map joueurs = (Map) donnees.get("joueurs"); + for(String joueur : joueurs.keySet()){ + playerNames.add(joueur); + List pActions=new ArrayList<>(); + List pActionsBasetime = new ArrayList<>(); + Object joueurPreData = joueurs.get(joueur); + if(joueurPreData==null){ + + }else { + Map joueurData = (Map) joueurPreData; + if (joueurData.containsKey("actions")) { + Map actions = (Map) joueurData.get("actions"); + for (Map.Entry paction : actions.entrySet()) { + pActions.add(paction.getKey()); + pActionsBasetime.add(parseTime(paction.getValue())); + } + } + } + playerActions.put(joueur,pActions); + playerActionsBaseTime.put(joueur,pActionsBasetime); + } + } + + // Maintenant, on crée les tableaux + this.triggeredTime = new long[playerNames.size()][]; + this.playerNames = new String[playerNames.size()]; + playerNames.toArray(this.playerNames); + this.playerActions = new String[playerActions.size()][]; + this.playerActionBaseTime = new Long[playerActions.size()][]; + int commonLength = commonActions.size(); + String[] commonActionsArray = new String[commonLength]; + Long[] commonActionsBaseTimeArray = new Long[commonLength]; + commonActions.toArray(commonActionsArray); + commonActionsBaseTime.toArray(commonActionsBaseTimeArray); + + for (int i = 0; i < this.playerNames.length; i++){ + int pactionsCount = commonLength+playerActions.get(this.playerNames[i]).size(); + + this.playerActions[i] = new String[pactionsCount]; + System.arraycopy(commonActionsArray,0,this.playerActions[i],0,commonLength); + System.arraycopy(playerActions.get(this.playerNames[i]).toArray(),0,this.playerActions[i],commonLength,pactionsCount-commonLength); + + this.playerActionBaseTime[i] = new Long[pactionsCount]; + System.arraycopy(commonActionsBaseTimeArray,0,this.playerActionBaseTime[i],0,commonLength); + System.arraycopy(playerActionsBaseTime.get(this.playerNames[i]).toArray(),0,this.playerActionBaseTime[i],commonLength,pactionsCount-commonLength); + + this.triggeredTime[i] = new long[pactionsCount]; + Arrays.fill(this.triggeredTime[i],0L); + } + + + }catch(Exception err){ + Log.e("MurderRead","J'ai pas réussi a lire le fichier, même si il est censé exister",err); + Toast.makeText(this,"Impossible de lire le fichier "+murderFileName,Toast.LENGTH_LONG).show(); + } + } + + public static long parseTime(String str){ + Matcher reconizeur = Pattern.compile("(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s?)?").matcher(str); + if(!reconizeur.matches()) + throw new IllegalArgumentException("Le temps '"+str+"' n'a pas été compris"); + Log.d("tempsLu",str); + for (int i = 0; i <= reconizeur.groupCount(); i++) + Log.d("tempsLu",i+"->"+(reconizeur.group(i)==null?"null":reconizeur.group(i))); + long h=0,m=0,s=0; + if(reconizeur.group(2)!=null)h = Long.parseLong(reconizeur.group(2)); + if(reconizeur.group(4)!=null)m = Long.parseLong(reconizeur.group(4)); + if(reconizeur.group(6)!=null)s = Long.parseLong(reconizeur.group(6)); + return 1000*(s+60*(m+60*h)); + + } + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.d("onCreate","Je demmande la permission"+ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)+ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)); + /* + if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || + ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ + ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},DATA_ACCESS_PERMISSION_REQUEST); + setContentView(R.layout.activity_main); + }else{ + setContentView(R.layout.activity_main); + generateData(); + initUI(); + } + */ + setContentView(R.layout.activity_main); + generateData(); + initUI(); + + } + /* + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + switch (requestCode){ + + case DATA_ACCESS_PERMISSION_REQUEST: + if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){ + generateData(); + initUI(); + }else{ + Toast.makeText(this,R.string.permission_denied_show_anger,Toast.LENGTH_SHORT).show(); + } + + + + } + } + + */ + + + void initUI(){ + + leftArrow = findViewById(R.id.leftPlayerSelect); + rightArrow = findViewById(R.id.rightPlayerSelect); + playerSelect = findViewById(R.id.playerSelect); + actionList = findViewById(R.id.actionListAdapter); + + leftArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.e("ui","coucou"); + prevPlayer(); + } + }); + rightArrow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + nextPlayer(); + } + }); + playerSelect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + selectPlayer(position); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + + ArrayAdapter playerAdapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_dropdown_item,playerNames); + playerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + playerSelect.setAdapter(playerAdapter); + + adapteurs = new ActionListAdapter[playerNames.length]; + triggeredTime = new long[playerNames.length][]; + for(int i = 0;ii)actionList.setAdapter(adapteurs[i]); + } + void nextPlayer(){ + playerSelect.setSelection((playerSelect.getSelectedItemPosition()+1)%playerSelect.getCount()); + } + void prevPlayer(){ + playerSelect.setSelection((playerSelect.getSelectedItemPosition()-1)%playerSelect.getCount()); + } + + @Override + public void onBackPressed() { + new AlertDialog.Builder(this) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.quitTitle) + .setMessage(R.string.quitText) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }) + .setNegativeButton(android.R.string.no,null) + .show(); + } + + public class ActionListAdapter extends BaseAdapter implements View.OnClickListener { + + String[] actionNames; + Long[] actionsBaseTime; + Button[] boutons; + Button boutonZero;// Pour corriger le bug du buton zéro + TextView[] timeLeftText; + TextView timeLeftZero; + Context ctx; + long[] triggeredTime; + + ActionListAdapter(String[] actionNames, Long[] actionsBaseTime, long[] triggeredTime, Context ctx){ + this.ctx = ctx; + this.actionNames = actionNames; + this.actionsBaseTime = actionsBaseTime; + this.triggeredTime = triggeredTime; + this.timeLeftText = new TextView[actionNames.length]; + this.boutons = new Button[actionNames.length]; + } + + @Override + public int getCount() { + return actionNames.length; + } + + + @Override + public Object getItem(int position) { + return actionNames[position]; + } + + @Override + public long getItemId(int position) { + return getItem(position).hashCode(); + } + + @Override + public View getView(int i, View convertView, ViewGroup parent) { + if(convertView==null){ + convertView = ((LayoutInflater) ctx + .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) + .inflate(R.layout.action_item,parent,false); + if(i==0)boutonZero = boutons[i]; + boutons[i] = convertView.findViewById(R.id.launchActionButton); + Log.d("Clicked","J'ai créé le bouton pour "+i+" sur "+parent+" et c'est "+boutons[i]); + boutons[i].setOnClickListener(this); + if(i==0)timeLeftZero = timeLeftText[i]; + timeLeftText[i] = convertView.findViewById(R.id.timeLeftText); + TextView titleText = convertView.findViewById(R.id.actionTitle); + titleText.setText(actionNames[i] +" --- "+ beautyfulTime(actionsBaseTime[i])); + } + + + return convertView; + } + + public void triggerAction(int i){ + if(i==0 && boutonZero!=null)this.boutonZero.setEnabled(false); + this.boutons[i].setEnabled(false); + triggeredTime[i] = System.currentTimeMillis(); + updateTimer(); + } + + public void updateTimer(){ + long time = System.currentTimeMillis(); + for(int i=0;i9?m+"m":"0"+m+"m")) + (s==0?"":(s>9?s+"s":"0"+s+"s")); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/tiktokmurder_icon.xml b/app/src/main/res/drawable/tiktokmurder_icon.xml new file mode 100644 index 0000000..2389276 --- /dev/null +++ b/app/src/main/res/drawable/tiktokmurder_icon.xml @@ -0,0 +1,51 @@ + + + + + + + diff --git a/app/src/main/res/drawable/tiktokmurder_icon_round.xml b/app/src/main/res/drawable/tiktokmurder_icon_round.xml new file mode 100644 index 0000000..144c7e4 --- /dev/null +++ b/app/src/main/res/drawable/tiktokmurder_icon_round.xml @@ -0,0 +1,51 @@ + + + + + + + diff --git a/app/src/main/res/layout/action_item.xml b/app/src/main/res/layout/action_item.xml new file mode 100644 index 0000000..f3f8fca --- /dev/null +++ b/app/src/main/res/layout/action_item.xml @@ -0,0 +1,31 @@ + + + +