Commit 924d7bf9 authored by Lückemeyer's avatar Lückemeyer
Browse files

claude added memorize screen, 2 iterations

parent e2362072
...@@ -9,6 +9,48 @@ import dev.lueckemeyer.vocoach.db.entity.Card; ...@@ -9,6 +9,48 @@ import dev.lueckemeyer.vocoach.db.entity.Card;
@Dao @Dao
public interface CardDao { public interface CardDao {
@Insert long insert(Card card); @Insert long insert(Card card);
@Query("SELECT * FROM card WHERE id = :id LIMIT 1") Card getByIdSync(int id);
@Query("SELECT * FROM card WHERE volet_id = :voletId ORDER BY id ASC") List<Card> getByVoletSync(int voletId); @Query("SELECT * FROM card WHERE id = :id LIMIT 1")
Card getByIdSync(int id);
@Query("SELECT * FROM card WHERE volet_id = :voletId ORDER BY id ASC")
List<Card> getByVoletSync(int voletId);
/**
* Returns all cards whose most recent try_record for the given direction
* places them in the given Leitner box.
* Cards with no try_record for this direction are excluded here —
* use getUnattemptedForDirectionSync for those.
*/
@Query("SELECT c.* FROM card c " +
"JOIN ( " +
" SELECT tr.leitner_state_id, ls.card_id, ls.box_number " +
" FROM try_record tr " +
" JOIN leitner_state ls ON ls.id = tr.leitner_state_id " +
" WHERE ls.direction = :direction " +
" AND tr.responded_at = ( " +
" SELECT MAX(tr2.responded_at) " +
" FROM try_record tr2 " +
" JOIN leitner_state ls2 ON ls2.id = tr2.leitner_state_id " +
" WHERE ls2.card_id = ls.card_id " +
" AND ls2.direction = :direction " +
" ) " +
") latest ON latest.card_id = c.id " +
"WHERE latest.box_number = :box " +
"GROUP BY c.id " +
"ORDER BY c.volet_id ASC, c.id ASC")
List<Card> getByBoxSync(int box, String direction);
/**
* Cards that have never been attempted in the given direction.
* These implicitly belong to box 1 for that direction.
*/
@Query("SELECT * FROM card c " +
"WHERE NOT EXISTS ( " +
" SELECT 1 FROM try_record tr " +
" JOIN leitner_state ls ON ls.id = tr.leitner_state_id " +
" WHERE ls.card_id = c.id AND ls.direction = :direction " +
") " +
"ORDER BY c.volet_id ASC, c.id ASC")
List<Card> getUnattemptedForDirectionSync(String direction);
} }
...@@ -9,6 +9,19 @@ import dev.lueckemeyer.vocoach.db.entity.Volet; ...@@ -9,6 +9,19 @@ import dev.lueckemeyer.vocoach.db.entity.Volet;
@Dao @Dao
public interface VoletDao { public interface VoletDao {
@Insert long insert(Volet volet); @Insert long insert(Volet volet);
@Query("SELECT * FROM volet WHERE unit_id = :unitId ORDER BY position ASC") List<Volet> getByUnitSync(int unitId);
@Query("SELECT * FROM volet ORDER BY id ASC") List<Volet> getAllSync(); @Query("SELECT * FROM volet WHERE unit_id = :unitId ORDER BY position ASC")
List<Volet> getByUnitSync(int unitId);
@Query("SELECT * FROM volet ORDER BY id ASC")
List<Volet> getAllSync();
/** Volets with their full book › unit › volet label, ordered by corpus position. */
@Query("SELECT v.id AS voletId, v.title AS voletTitle, " +
"u.title AS unitTitle, b.title AS bookTitle " +
"FROM volet v " +
"JOIN unit u ON u.id = v.unit_id " +
"JOIN book b ON b.id = u.book_id " +
"ORDER BY b.id ASC, u.position ASC, v.position ASC")
List<VoletWithContext> getAllWithContextSync();
} }
package dev.lueckemeyer.vocoach.db.dao;
/**
* Flat projection of volet + its unit + book names, used to populate
* the volet selection spinner on the Memorize screen.
*/
public class VoletWithContext {
public int voletId;
public String voletTitle;
public String unitTitle;
public String bookTitle;
/** Display label shown in the spinner drop-down. */
public String label() {
return bookTitle + " › " + unitTitle + " › " + voletTitle;
}
}
...@@ -49,6 +49,10 @@ public class HomeFragment extends Fragment { ...@@ -49,6 +49,10 @@ public class HomeFragment extends Fragment {
binding.btnStats.setOnClickListener(v -> binding.btnStats.setOnClickListener(v ->
Navigation.findNavController(v) Navigation.findNavController(v)
.navigate(R.id.action_home_to_stats)); .navigate(R.id.action_home_to_stats));
binding.btnMemorize.setOnClickListener(v ->
Navigation.findNavController(v)
.navigate(R.id.action_home_to_memorize));
} }
/** Returns true when the toggle is in Repeat position (ASC ordering). */ /** Returns true when the toggle is in Repeat position (ASC ordering). */
......
package dev.lueckemeyer.vocoach.ui.memorize;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import androidx.annotation.*;
import androidx.fragment.app.Fragment;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import dev.lueckemeyer.vocoach.databinding.FragmentMemorizeBinding;
import dev.lueckemeyer.vocoach.db.VocabDatabase;
import dev.lueckemeyer.vocoach.db.dao.VoletWithContext;
import dev.lueckemeyer.vocoach.db.entity.Card;
public class MemorizeFragment extends Fragment {
private FragmentMemorizeBinding binding;
private VocabDatabase db;
private final ExecutorService exec = Executors.newSingleThreadExecutor();
/** true = browse by volet, false = browse by Leitner box */
private boolean byVolet = true;
/**
* Direction for box mode.
* "fr_to_native" = French (left, toggle unchecked)
* "native_to_fr" = German (right, toggle checked)
*/
private String boxDirection = "fr_to_native";
private List<VoletWithContext> voletList = new ArrayList<>();
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMemorizeBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
db = VocabDatabase.getInstance(requireContext());
// ── Volet/Box toggle ─────────────────────────────────────────────────
binding.toggleMemorize.setChecked(false); // start on Volet
binding.toggleMemorize.setOnCheckedChangeListener((btn, checked) -> {
byVolet = !checked;
// Show direction toggle only in box mode
binding.rowDirection.setVisibility(checked ? View.VISIBLE : View.GONE);
refreshSpinner();
});
// ── Direction toggle (box mode only) ─────────────────────────────────
binding.toggleDirection.setChecked(false); // start on French
binding.toggleDirection.setOnCheckedChangeListener((btn, checked) -> {
boxDirection = checked ? "native_to_fr" : "fr_to_native";
if (!byVolet) loadTable(binding.spinnerSelection.getSelectedItemPosition());
});
// ── Spinner selection triggers table refresh ──────────────────────────
binding.spinnerSelection.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v,
int pos, long id) {
loadTable(pos);
}
@Override public void onNothingSelected(AdapterView<?> p) {}
});
// Initial load
refreshSpinner();
}
// ── Spinner population ────────────────────────────────────────────────────
private void refreshSpinner() {
if (byVolet) {
exec.execute(() -> {
voletList = db.voletDao().getAllWithContextSync();
List<String> labels = new ArrayList<>();
for (VoletWithContext v : voletList) labels.add(v.label());
requireActivity().runOnUiThread(() -> {
ArrayAdapter<String> adapter = new ArrayAdapter<>(
requireContext(),
android.R.layout.simple_spinner_item, labels);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
binding.spinnerSelection.setAdapter(adapter);
if (!labels.isEmpty()) loadTable(0);
});
});
} else {
List<String> boxes = new ArrayList<>();
for (int i = 1; i <= 6; i++) boxes.add("Box " + i);
ArrayAdapter<String> adapter = new ArrayAdapter<>(
requireContext(),
android.R.layout.simple_spinner_item, boxes);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
binding.spinnerSelection.setAdapter(adapter);
loadTable(0);
}
}
// ── Table loading ─────────────────────────────────────────────────────────
private void loadTable(int spinnerPos) {
binding.progressMemorize.setVisibility(View.VISIBLE);
binding.tableWords.removeAllViews();
exec.execute(() -> {
List<Card> cards;
if (byVolet) {
if (voletList.isEmpty()) { hideProgress(); return; }
int voletId = voletList.get(spinnerPos).voletId;
cards = db.cardDao().getByVoletSync(voletId);
} else {
int box = spinnerPos + 1; // spinner 0-based → box 1-based
cards = new ArrayList<>(db.cardDao().getByBoxSync(box, boxDirection));
if (box == 1) {
// Cards never attempted in this direction are implicitly in box 1
cards.addAll(db.cardDao().getUnattemptedForDirectionSync(boxDirection));
}
}
requireActivity().runOnUiThread(() -> {
binding.progressMemorize.setVisibility(View.GONE);
populateTable(cards);
});
});
}
private void hideProgress() {
requireActivity().runOnUiThread(() ->
binding.progressMemorize.setVisibility(View.GONE));
}
private void populateTable(List<Card> cards) {
TableLayout table = binding.tableWords;
table.removeAllViews();
table.addView(makeRow(true, "French", "German", "Type"));
if (cards.isEmpty()) {
table.addView(makeRow(false, "—", "No words found", ""));
return;
}
for (Card c : cards) {
table.addView(makeRow(false, nvl(c.french), nvl(c.nativeLang), nvl(c.wordType)));
}
}
// ── Row builder ───────────────────────────────────────────────────────────
private TableRow makeRow(boolean header, String col1, String col2, String col3) {
TableRow row = new TableRow(requireContext());
if (header) row.setBackgroundColor(0xFF6200EE);
String[] cells = {col1, col2, col3};
float[] weights = {2f, 2f, 1f};
for (int i = 0; i < cells.length; i++) {
TextView tv = new TextView(requireContext());
tv.setText(cells[i]);
tv.setPadding(12, 8, 12, 8);
if (header) {
tv.setTextColor(0xFFFFFFFF);
tv.setTypeface(null, Typeface.BOLD);
}
TableRow.LayoutParams lp = new TableRow.LayoutParams(
0, TableRow.LayoutParams.WRAP_CONTENT, weights[i]);
tv.setLayoutParams(lp);
row.addView(tv);
}
return row;
}
private static String nvl(String s) { return s != null ? s : ""; }
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
...@@ -62,6 +62,14 @@ ...@@ -62,6 +62,14 @@
android:layout_marginBottom="32dp" android:layout_marginBottom="32dp"
style="@style/Widget.MaterialComponents.Button"/> style="@style/Widget.MaterialComponents.Button"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_memorize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Memorize"
android:layout_marginBottom="16dp"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_stats" android:id="@+id/btn_stats"
android:layout_width="match_parent" android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- Volet / Box toggle -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Volet"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="end"
android:paddingEnd="12dp"/>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/toggle_memorize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Box"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="start"
android:paddingStart="12dp"/>
</LinearLayout>
<!-- Direction toggle — only visible in Box mode -->
<LinearLayout
android:id="@+id/row_direction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="12dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="French"
android:textAppearance="?attr/textAppearanceBody2"
android:gravity="end"
android:paddingEnd="12dp"/>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/toggle_direction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="German"
android:textAppearance="?attr/textAppearanceBody2"
android:gravity="start"
android:paddingStart="12dp"/>
</LinearLayout>
<!-- Selection spinner -->
<Spinner
android:id="@+id/spinner_selection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Progress indicator -->
<ProgressBar
android:id="@+id/progress_memorize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="gone"/>
<!-- Word table fills remaining space -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TableLayout
android:id="@+id/table_words"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1"/>
</ScrollView>
</LinearLayout>
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
<action <action
android:id="@+id/action_home_to_stats" android:id="@+id/action_home_to_stats"
app:destination="@id/statsFragment"/> app:destination="@id/statsFragment"/>
<action
android:id="@+id/action_home_to_memorize"
app:destination="@id/memorizeFragment"/>
</fragment> </fragment>
<fragment <fragment
...@@ -30,4 +33,9 @@ ...@@ -30,4 +33,9 @@
android:name="dev.lueckemeyer.vocoach.ui.stats.StatsFragment" android:name="dev.lueckemeyer.vocoach.ui.stats.StatsFragment"
android:label="Stats"/> android:label="Stats"/>
<fragment
android:id="@+id/memorizeFragment"
android:name="dev.lueckemeyer.vocoach.ui.memorize.MemorizeFragment"
android:label="Memorize"/>
</navigation> </navigation>
...@@ -650,7 +650,7 @@ code + .copy-button { ...@@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript"> <script type="text/javascript">
function configurationCacheProblems() { return ( function configurationCacheProblems() { return (
// begin-report-data // begin-report-data
{"diagnostics":[{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('namespace = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('compileSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('minSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('targetSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('viewBinding = <value>') instead."}]]},{"locations":[{"pluginId":"com.android.internal.application"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":6,"buildName":"VoCoach","requestedTasks":":app:bundleDebug","documentationLink":"https://docs.gradle.org/9.0.0/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}} {"diagnostics":[{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('namespace = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('compileSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('minSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('targetSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('viewBinding = <value>') instead."}]]},{"locations":[{"pluginId":"com.android.internal.application"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":6,"buildName":"VoCoach","requestedTasks":":app:assembleDebug","documentationLink":"https://docs.gradle.org/9.0.0/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data // end-report-data
);} );}
</script> </script>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment