7 Commits
Author SHA1 Message Date
xocko a625e20a56 Merge pull request 'Calendar Lite 1.6: bundled TLS 1.2, renamed from GingerCal, new icons, English months' (#1) from bundled-tls into main 2026-10-19 17:11:38 +00:00
XoséandClaude Opus 5.5 82acdb79f6 Calendar Lite 1.6: English month and weekday names in English mode
They came from the phone's locale, so a phone set to Spanish showed "Octubre 2026" with an
English interface (and I18nTest failed on any machine not set to English).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:11:24 +02:00
XoséandClaude Opus 5.5 478fc60527 README: direct https (no Pangolin needed), APK size, Bouncy Castle sources, test command
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:40:21 +02:00
XoséandClaude Opus 5.5 361adef1a0 Launcher icon back to the pack's blue
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:53:49 +02:00
XoséandClaude Opus 5.5 503beac559 Blue accent to match the blue icon (today ring, month arrows)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:53:23 +02:00
XoséandClaude Opus 5.5 9a4f6794d9 Launcher icon in the app's ginger (#D66E2A) instead of the pack's blue
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:30:18 +02:00
XoséandClaude Opus 5.5 748f6add54 Calendar Lite 1.5: GingerCal is now Calendar Lite, new icon and reminder icon
Renames the app (label, texts, User-Agent, PRODID, APK) and uses the new launcher icon pack
(ldpi to xhdpi, master in art/) instead of drawing one at build time. Reminders show a white
calendar glyph in the status bar (stat_notify, 18-48 px) instead of the system's colour
alarm clock, which didn't fit the Gingerbread bar. The package name, database and signing key
stay, so it installs over GingerCal and keeps its data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:57:48 +02:00
26 changed files with 46 additions and 78 deletions

No files matched your search

+2 -2
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.gingercal" package="org.gingercal"
android:versionCode="5" android:versionCode="7"
android:versionName="1.4"> android:versionName="1.6">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" />
+15 -13
View File
@@ -1,9 +1,9 @@
# GingerCal — Nextcloud CalDAV for Android 2.3 (Galaxy Mini) # Calendar Lite — Nextcloud CalDAV for Android 2.3 (Galaxy Mini)
A small native calendar client for Gingerbread (API 9/10). Built for a Samsung Galaxy Mini A small native calendar client for Gingerbread (API 9/10). Built for a Samsung Galaxy Mini
(GT-S5570, 240×320, Android 2.3.5) talking to Nextcloud, reached through Pangolin. (GT-S5570, 240×320, Android 2.3.5) talking to Nextcloud at its normal `https://` address.
**Since 1.4 it brings its own TLS 1.2** (Bouncy Castle, the same client as Minamp, with Mozilla's **Since 1.4 it brings its own TLS 1.2** (Bouncy Castle, the same client as Plexamp Lite, with Mozilla's
root certificates and keep-alive connections), like the iPod version does with BearSSL. Put the root certificates and keep-alive connections), like the iPod version does with BearSSL. Put the
normal `https://` Nextcloud address in Settings, at home or away: no bridge is needed. The bridge normal `https://` Nextcloud address in Settings, at home or away: no bridge is needed. The bridge
sections below are kept for reference; a bridge address (pinned certificate) still works. sections below are kept for reference; a bridge address (pinned certificate) still works.
@@ -131,22 +131,24 @@ you should turn `proxy_ssl_verify` on.
## Install on the phone ## Install on the phone
1. Settings, Applications, tick **Unknown sources**. 1. Settings, Applications, tick **Unknown sources**.
2. Copy `GingerCal.apk` to the SD card (USB) and open it with the file manager, or download it 2. Copy `CalendarLite.apk` to the SD card (USB) and open it with the file manager, or download it
over plain `http://` (the 2.3 browser can't open most HTTPS sites either). over plain `http://` (the 2.3 browser can't open most HTTPS sites either).
3. Open GingerCal, Menu, Settings. In Nextcloud create an app password: Settings, Security, 3. Open Calendar Lite, Menu, Settings. In Nextcloud create an app password: Settings, Security,
Devices & sessions. Fill in server, user, app password, then **Save and test connection**. Devices & sessions. Fill in server, user, app password, then **Save and test connection**.
Menu key: View (Month/Agenda), New event, Sync, Today, Calendars, Settings. Tap an event for Menu key: View (Month/Agenda), New event, Sync, Today, Calendars, Settings. Tap an event for
details, Edit and Delete. details, Edit and Delete.
If installation fails, check the file arrived whole (53 KB; some browsers save a truncated or If installation fails, check the file arrived whole (about 1 MB; some browsers save a truncated or
renamed `.apk.zip`) and that there are a few MB free on the internal storage. On a PC with renamed `.apk.zip`) and that there are a few MB free on the internal storage. On a PC with
`adb`, `adb install GingerCal.apk` prints the exact reason (`INSTALL_FAILED_...`). `adb`, `adb install CalendarLite.apk` prints the exact reason (`INSTALL_FAILED_...`).
## Building ## Building
Needs JDK 11+, Python 3 with Pillow, `d8` and `apksigner.jar` (Android SDK build-tools), and Needs JDK 11+, Python 3, `d8` and `apksigner.jar` (Android SDK build-tools),
`apktool.jar` (2.9+, which bundles Google's `aapt` and smali). No Gradle. `apktool.jar` (2.9+, which bundles Google's `aapt` and smali), and the Bouncy Castle sources renamed
to `com.minamp.bc` that Plexamp Lite's `tools/setup_toolchain.sh` prepares (`BC_SRC`, default
`~/android-toolchain/bcsrc`). No Gradle.
```sh ```sh
D8=d8 APKTOOL=~/apktool.jar APKSIGNER=$SDK/build-tools/34.0.0/lib/apksigner.jar ./build.sh D8=d8 APKTOOL=~/apktool.jar APKSIGNER=$SDK/build-tools/34.0.0/lib/apksigner.jar ./build.sh
@@ -165,7 +167,7 @@ over the existing app.
Tests (desktop JVM, need a CalDAV server such as Radicale on :5232 with user `xose`/`secret`): Tests (desktop JVM, need a CalDAV server such as Radicale on :5232 with user `xose`/`secret`):
```sh ```sh
javac -d out src/org/gingercal/*.java test/org/gingercal/*.java javac -d out src/org/gingercal/*.java $(ls test/org/gingercal/*.java | grep -v NetTest)
java -cp out org.gingercal.CoreTest # discovery, sync, recurrence, create/edit/delete java -cp out org.gingercal.CoreTest # discovery, sync, recurrence, create/edit/delete
java -cp out org.gingercal.RedirectTest # redirect handling (no server needed) java -cp out org.gingercal.RedirectTest # redirect handling (no server needed)
# the bundled TLS transport (needs the android.jar and Bouncy Castle sources to compile): # the bundled TLS transport (needs the android.jar and Bouncy Castle sources to compile):
@@ -181,12 +183,12 @@ declarations.
- `src/` CalDAV core, platform-neutral: discovery, PROPFIND/REPORT, iCalendar, sync, pinning - `src/` CalDAV core, platform-neutral: discovery, PROPFIND/REPORT, iCalendar, sync, pinning
- `android/` activities, sync service, alarms, SQLite cache, `NetHttp` transport - `android/` activities, sync service, alarms, SQLite cache, `NetHttp` transport
- `android/org/gingercal/net/` the bundled TLS 1.2 HTTP client from Minamp; `assets/roots/` Mozilla roots - `android/org/gingercal/net/` the bundled TLS 1.2 HTTP client from Plexamp Lite; `assets/roots/` Mozilla roots
- `stubs/` compile-only Android API 10 signatures (never packaged) - `stubs/` compile-only Android API 10 signatures (never packaged)
- `bridge/` legacy-TLS endpoint: standalone nginx (config, compose file), `npm/http.conf` for - `bridge/` legacy-TLS endpoint: standalone nginx (config, compose file), `npm/http.conf` for
Nginx Proxy Manager, certificate script Nginx Proxy Manager, certificate script
- `res/` app name; the icon is drawn at build time (mdpi + ldpi for the Galaxy Mini) - `res/` app name, launcher icon (ldpi to xhdpi; master in `art/`) and `stat_notify`, the white status-bar icon for reminders
- `tools/` icon, dex disassembler helper, zipalign, dex/API checkers, d8 workaround - `tools/` dex disassembler helper, zipalign, dex/API checkers, d8 workaround
## Security notes ## Security notes
+1 -1
View File
@@ -29,7 +29,7 @@ public class AlarmReceiver extends BroadcastReceiver {
static synchronized void acquire(Context c) { static synchronized void acquire(Context c) {
if (lock == null) { if (lock == null) {
PowerManager pm = (PowerManager) c.getApplicationContext().getSystemService("power"); PowerManager pm = (PowerManager) c.getApplicationContext().getSystemService("power");
lock = pm.newWakeLock(1 /* PARTIAL_WAKE_LOCK */, "GingerCal sync"); lock = pm.newWakeLock(1 /* PARTIAL_WAKE_LOCK */, "Calendar Lite sync");
lock.setReferenceCounted(false); lock.setReferenceCounted(false);
} }
lock.acquire(5 * 60 * 1000L); lock.acquire(5 * 60 * 1000L);
+1 -1
View File
@@ -9,7 +9,7 @@ public class GingerApp extends Application {
super.onCreate(); super.onCreate();
L.gl = !"en".equals(getSharedPreferences("gingercal", 0).getString("lang", "gl")); L.gl = !"en".equals(getSharedPreferences("gingercal", 0).getString("lang", "gl"));
org.gingercal.net.CertVerifier.setRootStore(new org.gingercal.net.AssetRoots(this)); org.gingercal.net.CertVerifier.setRootStore(new org.gingercal.net.AssetRoots(this));
org.gingercal.net.Http.USER_AGENT = "GingerCal/1.4 (Android 2.3)"; org.gingercal.net.Http.USER_AGENT = "CalendarLite/1.6 (Android 2.3)";
tlsTexts(); tlsTexts();
} }
+1 -1
View File
@@ -159,7 +159,7 @@ public class MainActivity extends Activity implements MonthView.Listener {
} }
TextView navArrow(String label, final int delta) { TextView navArrow(String label, final int delta) {
TextView b = App.text(this, label, 20, 0xFFD66E2A); // « »: Latin-1, always in the 2.3 font TextView b = App.text(this, label, 20, 0xFF3D8EF0); // « »: Latin-1, always in the 2.3 font
b.setGravity(17 /* Gravity.CENTER */); b.setGravity(17 /* Gravity.CENTER */);
int sel = App.sysDrawable(this, "list_selector_background"); int sel = App.sysDrawable(this, "list_selector_background");
if (sel != 0) b.setBackgroundResource(sel); // press highlight if (sel != 0) b.setBackgroundResource(sel); // press highlight
+1 -1
View File
@@ -28,7 +28,7 @@ public class MonthView extends View {
} }
static final int BG = 0xFF101418, GRID = 0xFF2A3036, WEEKDAY = 0xFF90A4AE, NUM = 0xFFECEFF1, static final int BG = 0xFF101418, GRID = 0xFF2A3036, WEEKDAY = 0xFF90A4AE, NUM = 0xFFECEFF1,
OTHER = 0xFF5C666E, TODAY = 0xFFD66E2A, SELECTED = 0xFF2E3B44; OTHER = 0xFF5C666E, TODAY = 0xFF3D8EF0, SELECTED = 0xFF2E3B44;
final float density; final float density;
final Paint fill = new Paint(1 /* ANTI_ALIAS_FLAG */), text = new Paint(1), line = new Paint(); final Paint fill = new Paint(1 /* ANTI_ALIAS_FLAG */), text = new Paint(1), line = new Paint();
+1 -1
View File
@@ -10,7 +10,7 @@ import java.util.concurrent.ExecutorService;
import org.gingercal.net.CertVerifier; import org.gingercal.net.CertVerifier;
/** /**
* Android 2.3 transport through the bundled TLS 1.2 client (org.gingercal.net, from Minamp): * Android 2.3 transport through the bundled TLS 1.2 client (org.gingercal.net, from Plexamp Lite):
* the phone's own TLS 1.0 can't reach Nextcloud, so this talks to the normal https:// address * the phone's own TLS 1.0 can't reach Nextcloud, so this talks to the normal https:// address
* directly, any method (PROPFIND/REPORT included), with keep-alive. A pinned certificate (a * directly, any method (PROPFIND/REPORT included), with keep-alive. A pinned certificate (a
* self-signed server or an old bridge) is still honoured. * self-signed server or an old bridge) is still honoured.
+3 -2
View File
@@ -43,8 +43,9 @@ public final class Reminders {
List<Ev> due = Db.get(c).startingBetween(Math.max(notified, now - 30 * ICal.MIN), now + m * ICal.MIN + 30000L); List<Ev> due = Db.get(c).startingBetween(Math.max(notified, now - 30 * ICal.MIN), now + m * ICal.MIN + 30000L);
NotificationManager nm = (NotificationManager) c.getSystemService("notification"); NotificationManager nm = (NotificationManager) c.getSystemService("notification");
long newest = notified; long newest = notified;
int icon = App.sysDrawable(c, "ic_popup_reminder"); // our own white status-bar glyph: the system's colour alarm-clock icon looks out of place up there
if (icon == 0) icon = App.sysDrawable(c, "ic_dialog_info"); int icon = c.getResources().getIdentifier("stat_notify", "drawable", c.getPackageName());
if (icon == 0) icon = App.sysDrawable(c, "ic_popup_reminder");
for (Ev e : due) { for (Ev e : due) {
Intent open = new Intent(c, MainActivity.class); Intent open = new Intent(c, MainActivity.class);
open.setFlags(0x10000000 /* FLAG_ACTIVITY_NEW_TASK */); open.setFlags(0x10000000 /* FLAG_ACTIVITY_NEW_TASK */);
+1 -1
View File
@@ -27,7 +27,7 @@ public class SettingsActivity extends Activity {
@Override @Override
protected void onCreate(Bundle b) { protected void onCreate(Bundle b) {
super.onCreate(b); super.onCreate(b);
setTitle(L.t("GingerCal settings")); setTitle(L.t("Calendar Lite settings"));
LinearLayout f = App.vbox(this); LinearLayout f = App.vbox(this);
int p = App.dp(this, 8); int p = App.dp(this, 8);
f.setPadding(p, p, p, p); f.setPadding(p, p, p, p);
+1 -1
View File
@@ -37,7 +37,7 @@ import com.minamp.bc.crypto.util.PublicKeyFactory;
* Minimal Web PKI path validation for the bundled TLS stack: * Minimal Web PKI path validation for the bundled TLS stack:
* hostname match, validity window, signature chain up to a bundled Mozilla root. * hostname match, validity window, signature chain up to a bundled Mozilla root.
* Optionally one pinned leaf certificate (SHA-256) is trusted as-is, for self-signed servers. * Optionally one pinned leaf certificate (SHA-256) is trusted as-is, for self-signed servers.
* Shared with Minamp (tools/tlskit in the iOS ports' history); keep the copies in sync. * Shared with Plexamp Lite (tools/tlskit in the iOS ports' history); keep the copies in sync.
*/ */
public final class CertVerifier { public final class CertVerifier {
+2 -2
View File
@@ -33,11 +33,11 @@ import com.minamp.bc.tls.crypto.impl.bc.BcTlsCrypto;
/** /**
* Small HTTP/1.1 client with its own TLS 1.2 (Bouncy Castle), keep-alive pooling and * Small HTTP/1.1 client with its own TLS 1.2 (Bouncy Castle), keep-alive pooling and
* session resumption. Android 2.x's built-in SSL only speaks TLS 1.0 and lacks today's roots, * session resumption. Android 2.x's built-in SSL only speaks TLS 1.0 and lacks today's roots,
* so every request in the app goes through here. From Minamp; keep the copies in sync. * so every request in the app goes through here. From Plexamp Lite; keep the copies in sync.
*/ */
public final class Http { public final class Http {
public static String USER_AGENT = "Minamp/1.0"; public static String USER_AGENT = "PlexampLite/1.0";
/** Optional HTTP CONNECT proxy, only used when running the networking code on a desktop JVM. */ /** Optional HTTP CONNECT proxy, only used when running the networking code on a desktop JVM. */
public static String proxyHost; public static String proxyHost;
Binary file not shown.

After

Width:  |  Height:  |  Size: 973 KiB

+3 -3
View File
@@ -1,5 +1,5 @@
TASK FOR CLAUDE CODE (on the Pangolin server, 141.227.129.182) TASK FOR CLAUDE CODE (on the Pangolin server, 141.227.129.182)
Add a raw TCP resource on port 8443 so the GingerCal app (Android 2.3) can reach Nextcloud CalDAV Add a raw TCP resource on port 8443 so the Calendar Lite app (Android 2.3) can reach Nextcloud CalDAV
================================================================================================== ==================================================================================================
CONTEXT CONTEXT
@@ -72,7 +72,7 @@ STEPS
7. Pangolin dashboard (the user does this, or guide them through it): 7. Pangolin dashboard (the user does this, or guide them through it):
- Org of the home server, Resources, Add Resource, type "Raw TCP/UDP resource". - Org of the home server, Resources, Add Resource, type "Raw TCP/UDP resource".
- Name: GingerCal CalDAV. Protocol: TCP. Public port: 8443. - Name: Calendar Lite CalDAV. Protocol: TCP. Public port: 8443.
- Site: the site whose newt runs on the home server 172.30.1.123 (most likely the "casa" site). - Site: the site whose newt runs on the home server 172.30.1.123 (most likely the "casa" site).
- Target: IP 172.30.1.123, port 8443. Leave "Enable Proxy Protocol" OFF (the bridge doesn't - Target: IP 172.30.1.123, port 8443. Leave "Enable Proxy Protocol" OFF (the bridge doesn't
expect it; enabling only one side breaks every connection). expect it; enabling only one side breaks every connection).
@@ -104,7 +104,7 @@ STEPS
PHONE SETUP (after step 8 passes) PHONE SETUP (after step 8 passes)
--------------------------------- ---------------------------------
GingerCal, Menu, Settings: Calendar Lite, Menu, Settings:
Server: https://141.227.129.182:8443 (any *.oxose.org name works too, e.g. Server: https://141.227.129.182:8443 (any *.oxose.org name works too, e.g.
https://cal-old.oxose.org:8443: raw TCP ignores the hostname and the app pins the https://cal-old.oxose.org:8443: raw TCP ignores the hostname and the app pins the
certificate, not the name) certificate, not the name)
+10 -12
View File
@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# Builds GingerCal.apk for Android 2.3 (API 10) without Gradle. # Builds CalendarLite.apk for Android 2.3 (API 10) without Gradle.
# #
# Needs: JDK 11+ (javac, keytool), python3 with Pillow (icon), and three tools: # Needs: JDK 11+ (javac, keytool), python3, and three tools:
# D8 command that runs d8 (Android SDK build-tools; default "d8" on PATH) # D8 command that runs d8 (Android SDK build-tools; default "d8" on PATH)
# APKTOOL path to apktool.jar (https://apktool.org; bundles aapt and smali) # APKTOOL path to apktool.jar (https://apktool.org; bundles aapt and smali)
# APKSIGNER path to apksigner.jar (Android SDK build-tools/<ver>/lib/apksigner.jar) # APKSIGNER path to apksigner.jar (Android SDK build-tools/<ver>/lib/apksigner.jar)
@@ -20,7 +20,7 @@ VERSION_CODE=$(sed -n 's/.*android:versionCode="\([0-9]*\)".*/\1/p' AndroidManif
VERSION_NAME=$(sed -n 's/.*android:versionName="\([^"]*\)".*/\1/p' AndroidManifest.xml) VERSION_NAME=$(sed -n 's/.*android:versionName="\([^"]*\)".*/\1/p' AndroidManifest.xml)
rm -rf "$OUT" rm -rf "$OUT"
mkdir -p "$OUT/stubs" "$OUT/classes" "$OUT/dex" "$OUT/apk/res/drawable" "$OUT/apk/res/drawable-ldpi" mkdir -p "$OUT/stubs" "$OUT/classes" "$OUT/dex" "$OUT/apk/res"
# 0. every interface string must have its Galician translation # 0. every interface string must have its Galician translation
python3 tools/check_i18n.py . python3 tools/check_i18n.py .
@@ -46,13 +46,11 @@ java -cp "$APKTOOL:$OUT/tools" Disassemble "$OUT/dex/classes.dex" "$OUT/apk/smal
# 3. resources + manifest, compiled by real aapt (v1, the tool of the Gingerbread era) # 3. resources + manifest, compiled by real aapt (v1, the tool of the Gingerbread era)
cp AndroidManifest.xml "$OUT/apk/" cp AndroidManifest.xml "$OUT/apk/"
cp -r res/values "$OUT/apk/res/" cp -r res/* "$OUT/apk/res/" # launcher icon (ldpi..xhdpi) and the status-bar reminder icon
cp -r assets "$OUT/apk/" # Mozilla root certificates for the bundled TLS cp -r assets "$OUT/apk/" # Mozilla root certificates for the bundled TLS
python3 tools/mkicon.py "$OUT/apk/res/drawable/icon.png" 48
python3 tools/mkicon.py "$OUT/apk/res/drawable-ldpi/icon.png" 36
cat > "$OUT/apk/apktool.yml" <<EOF cat > "$OUT/apk/apktool.yml" <<EOF
version: 2.9.3 version: 2.9.3
apkFileName: GingerCal.apk apkFileName: CalendarLite.apk
isFrameworkApk: false isFrameworkApk: false
usesFramework: usesFramework:
ids: ids:
@@ -80,14 +78,14 @@ java -jar "$APKTOOL" -q b --use-aapt1 -api 8 -f -o "$OUT/unsigned.apk" "$OUT/apk
# attributes; apksigner picks exactly that for --min-sdk-version 8. (jarsigner does not.) # attributes; apksigner picks exactly that for --min-sdk-version 8. (jarsigner does not.)
if [ ! -f "$KS" ]; then if [ ! -f "$KS" ]; then
keytool -genkeypair -keystore "$KS" -storetype PKCS12 -storepass android -keypass android \ keytool -genkeypair -keystore "$KS" -storetype PKCS12 -storepass android -keypass android \
-alias gingercal -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 10000 -dname "CN=GingerCal" 2>/dev/null -alias gingercal -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 10000 -dname "CN=Calendar Lite" 2>/dev/null
fi fi
java -jar "$APKSIGNER" sign --ks "$KS" --ks-key-alias gingercal --ks-pass pass:android --key-pass pass:android \ java -jar "$APKSIGNER" sign --ks "$KS" --ks-key-alias gingercal --ks-pass pass:android --key-pass pass:android \
--min-sdk-version 8 --v1-signing-enabled true --v2-signing-enabled false --v3-signing-enabled false \ --min-sdk-version 8 --v1-signing-enabled true --v2-signing-enabled false --v3-signing-enabled false \
--v4-signing-enabled false --out "$OUT/signed.apk" "$OUT/unsigned.apk" --v4-signing-enabled false --out "$OUT/signed.apk" "$OUT/unsigned.apk"
python3 tools/zipalign.py "$OUT/signed.apk" GingerCal.apk python3 tools/zipalign.py "$OUT/signed.apk" CalendarLite.apk
# 5. refuse to ship anything Android 2.3 would reject # 5. refuse to ship anything Android 2.3 would reject
java -jar "$APKSIGNER" verify --min-sdk-version 8 --max-sdk-version 10 GingerCal.apk java -jar "$APKSIGNER" verify --min-sdk-version 8 --max-sdk-version 10 CalendarLite.apk
python3 tools/check_dex.py GingerCal.apk python3 tools/check_dex.py CalendarLite.apk
ls -l GingerCal.apk ls -l CalendarLite.apk
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">GingerCal</string> <string name="app_name">Calendar Lite</string>
</resources> </resources>
+1 -1
View File
@@ -431,7 +431,7 @@ public class ICal {
List<String> l = new ArrayList<String>(); List<String> l = new ArrayList<String>();
l.add("BEGIN:VCALENDAR"); l.add("BEGIN:VCALENDAR");
l.add("VERSION:2.0"); l.add("VERSION:2.0");
l.add("PRODID:-//GingerCal//Android 2.3//EN"); l.add("PRODID:-//CalendarLite//Android 2.3//EN");
l.add("BEGIN:VEVENT"); l.add("BEGIN:VEVENT");
l.add("UID:" + uid); l.add("UID:" + uid);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
+2 -2
View File
@@ -42,7 +42,7 @@ public final class L {
static final String[] GL_DAYS_SHORT = {"", "dom", "lun", "mar", "mér", "xov", "ven", "sáb"}; static final String[] GL_DAYS_SHORT = {"", "dom", "lun", "mar", "mér", "xov", "ven", "sáb"};
public static DateFormatSymbols symbols() { public static DateFormatSymbols symbols() {
if (!gl) return new DateFormatSymbols(Locale.getDefault()); if (!gl) return new DateFormatSymbols(Locale.US); // English names, whatever the phone's language
DateFormatSymbols s = new DateFormatSymbols(Locale.US); DateFormatSymbols s = new DateFormatSymbols(Locale.US);
s.setMonths(GL_MONTHS); s.setMonths(GL_MONTHS);
s.setShortMonths(GL_MONTHS_SHORT); s.setShortMonths(GL_MONTHS_SHORT);
@@ -149,7 +149,7 @@ public final class L {
put("Default calendar", "Calendario predeterminado"); put("Default calendar", "Calendario predeterminado");
// settings // settings
put("GingerCal settings", "Configuración de GingerCal"); put("Calendar Lite settings", "Configuración de Calendar Lite");
put("Nextcloud server: your normal https:// address. This app brings its own modern TLS, so no bridge is needed, at home or away. Use an app password, not your real one.", put("Nextcloud server: your normal https:// address. This app brings its own modern TLS, so no bridge is needed, at home or away. Use an app password, not your real one.",
"Servidor Nextcloud: o teu enderezo https:// de sempre. Esta aplicación trae o seu propio TLS moderno, así que non fai falta ningunha ponte, nin na casa nin fóra. Usa un contrasinal de aplicación, non o teu contrasinal real."); "Servidor Nextcloud: o teu enderezo https:// de sempre. Esta aplicación trae o seu propio TLS moderno, así que non fai falta ningunha ponte, nin na casa nin fóra. Usa un contrasinal de aplicación, non o teu contrasinal real.");
put("Server address", "Enderezo do servidor"); put("Server address", "Enderezo do servidor");
-33
View File
@@ -1,33 +0,0 @@
#!/usr/bin/env python3
"""Draws the launcher icon: a little calendar page in ginger tones.
usage: mkicon.py out.png [size] (48 = mdpi, 36 = ldpi like the Galaxy Mini)"""
import sys
from PIL import Image, ImageDraw
S = 4 # supersample then shrink for smooth edges
W = 48 * S
img = Image.new("RGBA", (W, W), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
# shadow
d.rounded_rectangle((5 * S, 7 * S, 45 * S, 46 * S), radius=6 * S, fill=(0, 0, 0, 90))
# page
d.rounded_rectangle((3 * S, 5 * S, 43 * S, 44 * S), radius=6 * S, fill=(250, 246, 238, 255))
# ginger header band
d.rounded_rectangle((3 * S, 5 * S, 43 * S, 17 * S), radius=6 * S, fill=(214, 110, 42, 255))
d.rectangle((3 * S, 11 * S, 43 * S, 17 * S), fill=(214, 110, 42, 255))
# binder rings
for x in (13, 33):
d.rounded_rectangle(((x - 2) * S, 2 * S, (x + 2) * S, 10 * S), radius=2 * S, fill=(90, 60, 40, 255))
# day grid, one day highlighted
for row in range(3):
for col in range(4):
x0 = (8 + col * 8.5) * S
y0 = (21 + row * 7.5) * S
box = (x0, y0, x0 + 5.5 * S, y0 + 5 * S)
if (row, col) == (1, 2):
d.rounded_rectangle(box, radius=1.5 * S, fill=(0, 130, 201, 255)) # Nextcloud blue
else:
d.rounded_rectangle(box, radius=1.5 * S, fill=(200, 188, 172, 255))
size = int(sys.argv[2]) if len(sys.argv) > 2 else 48
img = img.resize((size, size), Image.LANCZOS)
img.save(sys.argv[1] if len(sys.argv) > 1 else "icon.png", optimize=True)