From 1526256faab488ce3c7aaa40d4e6fa023bbf816b Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Fri, 31 Jul 2026 09:02:25 -0600 Subject: [PATCH 1/4] =?UTF-8?q?ADFA-4958:=20action=20sheet=20subtitle=20sh?= =?UTF-8?q?ows=20size=20(project=20=C2=B7=20state=20=C2=B7=20size,=20?= =?UTF-8?q?=C2=A75.3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module action sheet header subtitle was "project · state"; the handoff §5.3 asks for "project · state · size". Append "≈ " from the existing ModuleSizes/ByteFormatter (same source as the detail chip); omitted when the size is unknown (matomo/maps). Wording/format only, no behavior change. --- .../org/iiab/controller/redesign/ModuleActionSheet.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java index e8ff5cdc..47f62636 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java @@ -79,7 +79,12 @@ public static void show(Activity act, String endpoint, String title, int iconRes hcol.addView(tv); TextView subtitle = new TextView(ctx); String project = (card != null) ? act.getString(card.subRes) : ""; - subtitle.setText(project.isEmpty() ? stateLabel(act, state) : project + " · " + stateLabel(act, state)); + long bytes = ModuleSizes.bytesFor(ctx, key); // ADFA-4958 §5.3: subtitle is project · state · size + StringBuilder sub = new StringBuilder(); + if (!project.isEmpty()) sub.append(project).append(" · "); + sub.append(stateLabel(act, state)); + if (bytes >= 0) sub.append(" · ≈ ").append(org.iiab.controller.util.ByteFormatter.toHuman(bytes)); + subtitle.setText(sub.toString()); subtitle.setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodySmall); subtitle.setTextColor(ContextCompat.getColor(ctx, R.color.k2go_muted)); hcol.addView(subtitle); From 19bab17613c41347cec1ac7ab2fc5016deeeb949 Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Fri, 31 Jul 2026 09:10:21 -0600 Subject: [PATCH 2/4] ADFA-4958: maps shows a curated "200 MB+" size floor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit maps has no single install size — its footprint depends on the layers/levels the user selects and grows steeply. Instead of "NA", show a curated floor "200 MB+" (ModuleCards.sizeLabelRes) in both the detail size chip and the action-sheet subtitle. The "+" conveys the floor, so the chip drops the "≈" prefix for maps. Measured modules are unchanged. --- .../org/iiab/controller/redesign/ModuleActionSheet.java | 6 ++++-- .../java/org/iiab/controller/redesign/ModuleCards.java | 8 ++++++++ .../iiab/controller/redesign/ModuleDetailFragment.java | 5 +++-- controller/app/src/main/res/values/strings_k2go.xml | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java index 47f62636..978bff33 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleActionSheet.java @@ -79,11 +79,13 @@ public static void show(Activity act, String endpoint, String title, int iconRes hcol.addView(tv); TextView subtitle = new TextView(ctx); String project = (card != null) ? act.getString(card.subRes) : ""; - long bytes = ModuleSizes.bytesFor(ctx, key); // ADFA-4958 §5.3: subtitle is project · state · size + int sizeRes = ModuleCards.sizeLabelRes(key); // ADFA-4958 §5.3: subtitle is project · state · size + long bytes = ModuleSizes.bytesFor(ctx, key); StringBuilder sub = new StringBuilder(); if (!project.isEmpty()) sub.append(project).append(" · "); sub.append(stateLabel(act, state)); - if (bytes >= 0) sub.append(" · ≈ ").append(org.iiab.controller.util.ByteFormatter.toHuman(bytes)); + if (sizeRes != 0) sub.append(" · ").append(act.getString(sizeRes)); + else if (bytes >= 0) sub.append(" · ≈ ").append(org.iiab.controller.util.ByteFormatter.toHuman(bytes)); subtitle.setText(sub.toString()); subtitle.setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodySmall); subtitle.setTextColor(ContextCompat.getColor(ctx, R.color.k2go_muted)); diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java index 2c88403d..578da17c 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java @@ -114,6 +114,14 @@ public static String license(String key) { } } + /** ADFA-4958: curated size label for modules whose real footprint is selection-dependent + * (maps grows with the layers/levels the user picks), shown instead of a single measured + * value. 0 -> fall back to the measured ModuleSizes value. */ + public static int sizeLabelRes(String key) { + if ("maps".equals(key)) return R.string.k2go_mod_maps_size; + return 0; + } + /** ADFA-4958: "What it includes" line — makes module-vs-content explicit. 0 -> hide. */ public static int includesRes(String key) { if (key == null) return 0; diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java index 79ceaaf0..86124412 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java @@ -66,9 +66,10 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c // ADFA-4958: meta chips (size / version / Runs offline), "What it includes", and license. LinearLayout chips = root.findViewById(R.id.k2go_moddet_chips); + int sizeRes = ModuleCards.sizeLabelRes(c.key()); // ADFA-4958: maps uses a curated "200 MB+" floor long bytes = ModuleSizes.bytesFor(requireContext(), c.key()); - String sizeText = (bytes >= 0) - ? "\u2248 " + org.iiab.controller.util.ByteFormatter.toHuman(bytes) + String sizeText = (sizeRes != 0) ? getString(sizeRes) + : (bytes >= 0) ? "\u2248 " + org.iiab.controller.util.ByteFormatter.toHuman(bytes) : "\u2248 NA"; chips.addView(chip(sizeText, R.color.k2go_teal)); String ver = ModuleCards.version(c.key()); diff --git a/controller/app/src/main/res/values/strings_k2go.xml b/controller/app/src/main/res/values/strings_k2go.xml index 4f3b0e09..07d84a09 100644 --- a/controller/app/src/main/res/values/strings_k2go.xml +++ b/controller/app/src/main/res/values/strings_k2go.xml @@ -664,6 +664,7 @@ Offline world maps to browse and search on the device. Pick the layers and region, then it builds into your system. Runs offline + 200 MB+ What it includes License · %1$s Sample courses included — add more in Get more. From 05641a72b294676776b6989af8aa8f3623061232 Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Fri, 31 Jul 2026 09:34:43 -0600 Subject: [PATCH 3/4] ADFA-4958: matomo size (~114 MB) + "Demo" chip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - matomo gets a curated size "≈ 114 MB" (from a manual install measurement; incl. MariaDB + the Matomo tarball). Now every module shows a size: kolibri/calibreweb/ kiwix/code measured, maps "200 MB+", matomo "≈ 114 MB". - matomo is a demo/example module (runs, but not a real production feature): the detail shows a "Demo" chip (ModuleCards.isDemo). Label only, no behavior change. --- .../java/org/iiab/controller/redesign/ModuleCards.java | 7 +++++++ .../org/iiab/controller/redesign/ModuleDetailFragment.java | 1 + controller/app/src/main/res/values/strings_k2go.xml | 2 ++ 3 files changed, 10 insertions(+) diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java index 578da17c..f86c90ef 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleCards.java @@ -119,9 +119,16 @@ public static String license(String key) { * value. 0 -> fall back to the measured ModuleSizes value. */ public static int sizeLabelRes(String key) { if ("maps".equals(key)) return R.string.k2go_mod_maps_size; + if ("matomo".equals(key)) return R.string.k2go_mod_matomo_size; // ADFA-4958: curated (~114 MB, incl. MariaDB + tarball) return 0; } + /** ADFA-4958: matomo ships as a demo/example module — it runs, but it is not a real production + * feature; flagged so the detail can show a "Demo" chip. */ + public static boolean isDemo(String key) { + return "matomo".equals(key); + } + /** ADFA-4958: "What it includes" line — makes module-vs-content explicit. 0 -> hide. */ public static int includesRes(String key) { if (key == null) return 0; diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java index 86124412..4403ef17 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java @@ -75,6 +75,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c String ver = ModuleCards.version(c.key()); if (ver != null) chips.addView(chip("v" + ver, R.color.k2go_teal)); chips.addView(chip(getString(R.string.k2go_mod_runs_offline), R.color.k2go_leaf)); + if (ModuleCards.isDemo(c.key())) chips.addView(chip(getString(R.string.k2go_mod_demo), R.color.k2go_amber_text)); // ADFA-4958 int inc = ModuleCards.includesRes(c.key()); if (inc != 0) { diff --git a/controller/app/src/main/res/values/strings_k2go.xml b/controller/app/src/main/res/values/strings_k2go.xml index 07d84a09..d904bc1f 100644 --- a/controller/app/src/main/res/values/strings_k2go.xml +++ b/controller/app/src/main/res/values/strings_k2go.xml @@ -665,6 +665,8 @@ Runs offline 200 MB+ + ≈ 114 MB + Demo What it includes License · %1$s Sample courses included — add more in Get more. From 8154946593f7ac2047a6841c5fe21ac73fd220f4 Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Fri, 31 Jul 2026 09:58:45 -0600 Subject: [PATCH 4/4] ADFA-4958: meta chips + Restore are outlined pills (teal text was invisible) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size/version chips (and the HIDDEN → Restore pill) used k2go_chip_bg, a solid teal fill, with teal text on top — so the text was invisible (empty teal pills). That drawable is the "selected" filled pill used elsewhere, so leave it as is and make these render as outlined pills instead (transparent fill, colored stroke + text), per the handoff (§5.4 chips, §5.7 Restore). Runs offline / Demo were already legible; now size, version and Restore are too. --- .../iiab/controller/redesign/ModuleDetailFragment.java | 10 ++++++++-- .../iiab/controller/redesign/ModuleHubFragment.java | 5 +---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java index 4403ef17..20c50a02 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleDetailFragment.java @@ -122,8 +122,14 @@ private TextView chip(String text, int colorRes) { TextView t = new TextView(requireContext()); t.setText(text); t.setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_LabelMedium); - t.setTextColor(ContextCompat.getColor(requireContext(), colorRes)); - t.setBackgroundResource(R.drawable.k2go_chip_bg); + int color = ContextCompat.getColor(requireContext(), colorRes); // ADFA-4958 §5.4: outlined pill (teal-on-teal fill was invisible) + t.setTextColor(color); + android.graphics.drawable.GradientDrawable bg = new android.graphics.drawable.GradientDrawable(); + bg.setShape(android.graphics.drawable.GradientDrawable.RECTANGLE); + bg.setColor(android.graphics.Color.TRANSPARENT); + bg.setCornerRadius(11 * d); + bg.setStroke(Math.max(1, Math.round(1.4f * d)), color); + t.setBackground(bg); int hp = Math.round(10 * d), vp = Math.round(5 * d); t.setPadding(hp, vp, hp, vp); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleHubFragment.java b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleHubFragment.java index 18d6379d..c3d9e7d3 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/ModuleHubFragment.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/ModuleHubFragment.java @@ -220,10 +220,7 @@ private void addHiddenSection() { col.addView(sub); row.addView(col, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)); - TextView restore = new TextView(requireContext()); - restore.setText(R.string.k2go_mod_restore); - restore.setTextColor(ContextCompat.getColor(requireContext(), R.color.k2go_teal)); - restore.setBackgroundResource(R.drawable.k2go_chip_bg); + TextView restore = statePill(getString(R.string.k2go_mod_restore), R.color.k2go_teal); // ADFA-4958 §5.7: outlined teal pill restore.setPadding(px(14), px(6), px(14), px(6)); restore.setOnClickListener(v -> { HiddenModules.remove(requireContext(), key); buildCards(); }); row.addView(restore);