Skip and docs

This commit is contained in:
Daniel Arantes Loverde
2026-02-04 08:42:32 -03:00
commit 78daaf1927
114 changed files with 3326 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
import java.util.Properties
plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.android.application)
id("skip-build-plugin")
}
skip {
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.fromTarget(libs.versions.jvm.get().toString())
}
}
android {
namespace = group as String
compileSdk = libs.versions.android.sdk.compile.get().toInt()
compileOptions {
sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get())
}
packaging {
jniLibs {
keepDebugSymbols.add("**/*.so")
pickFirsts.add("**/*.so")
// this option will compress JNI .so files
useLegacyPackaging = true
}
}
defaultConfig {
minSdk = libs.versions.android.sdk.min.get().toInt()
targetSdk = libs.versions.android.sdk.compile.get().toInt()
// skip.tools.skip-build-plugin will automatically use Skip.env properties for:
// applicationId = ANDROID_APPLICATION_ID ?? PRODUCT_BUNDLE_IDENTIFIER
// versionCode = CURRENT_PROJECT_VERSION
// versionName = MARKETING_VERSION
}
buildFeatures {
buildConfig = true
}
lint {
disable.add("Instantiatable")
disable.add("MissingPermission")
}
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
// default signing configuration tries to load from keystore.properties
// see: https://skip.tools/docs/deployment/#export-signing
signingConfigs {
val keystorePropertiesFile = file("keystore.properties")
create("release") {
if (keystorePropertiesFile.isFile) {
val keystoreProperties = Properties()
keystoreProperties.load(keystorePropertiesFile.inputStream())
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
} else {
// when there is no keystore.properties file, fall back to signing with debug config
keyAlias = signingConfigs.getByName("debug").keyAlias
keyPassword = signingConfigs.getByName("debug").keyPassword
storeFile = signingConfigs.getByName("debug").storeFile
storePassword = signingConfigs.getByName("debug").storePassword
}
}
}
buildTypes {
release {
signingConfig = signingConfigs.findByName("release")
isMinifyEnabled = true
isShrinkResources = true
isDebuggable = false // can be set to true for debugging release build, but needs to be false when uploading to store
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
}

View File

@@ -0,0 +1,10 @@
-keeppackagenames **
-keep class skip.** { *; }
-keep class tools.skip.** { *; }
-keep class kotlin.jvm.functions.** {*;}
-keep class com.sun.jna.** { *; }
-dontwarn java.awt.**
-keep class * implements com.sun.jna.** { *; }
-keep class * implements skip.bridge.** { *; }
-keep class **._ModuleBundleAccessor_* { *; }
-keep class pedi.foods.** { *; }

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This AndroidManifest.xml template was generated by Skip -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<!-- example permissions for using device location -->
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> -->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> -->
<!-- permissions needed for using the internet or an embedded WebKit browser -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> -->
<application
android:label="${PRODUCT_NAME}"
android:name=".AndroidAppMain"
android:supportsRtl="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,167 @@
package pedi.foods
import skip.lib.*
import skip.model.*
import skip.foundation.*
import skip.ui.*
import android.Manifest
import android.app.Application
import android.graphics.Color as AndroidColor
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.SystemBarStyle
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.platform.LocalContext
import androidx.compose.material3.MaterialTheme
import androidx.core.app.ActivityCompat
internal val logger: SkipLogger = SkipLogger(subsystem = "pedi.foods", category = "PediFoods")
private typealias AppRootView = PediFoodsRootView
private typealias AppDelegate = PediFoodsAppDelegate
/// AndroidAppMain is the `android.app.Application` entry point, and must match `application android:name` in the AndroidMainfest.xml file.
open class AndroidAppMain: Application {
constructor() {
}
override fun onCreate() {
super.onCreate()
logger.info("starting app")
ProcessInfo.launch(applicationContext)
AppDelegate.shared.onInit()
}
companion object {
}
}
/// AndroidAppMain is initial `androidx.appcompat.app.AppCompatActivity`, and must match `activity android:name` in the AndroidMainfest.xml file.
open class MainActivity: AppCompatActivity {
constructor() {
}
override fun onCreate(savedInstanceState: android.os.Bundle?) {
super.onCreate(savedInstanceState)
logger.info("starting activity")
UIApplication.launch(this)
enableEdgeToEdge()
setContent {
val saveableStateHolder = rememberSaveableStateHolder()
saveableStateHolder.SaveableStateProvider(true) {
PresentationRootView(ComposeContext())
SideEffect { saveableStateHolder.removeState(true) }
}
}
AppDelegate.shared.onLaunch()
// Example of requesting permissions on startup.
// These must match the permissions in the AndroidManifest.xml file.
//let permissions = listOf(
// Manifest.permission.ACCESS_COARSE_LOCATION,
// Manifest.permission.ACCESS_FINE_LOCATION
// Manifest.permission.CAMERA,
// Manifest.permission.WRITE_EXTERNAL_STORAGE,
//)
//let requestTag = 1
//ActivityCompat.requestPermissions(self, permissions.toTypedArray(), requestTag)
}
override fun onStart() {
logger.info("onStart")
super.onStart()
}
override fun onResume() {
super.onResume()
AppDelegate.shared.onResume()
}
override fun onPause() {
super.onPause()
AppDelegate.shared.onPause()
}
override fun onStop() {
super.onStop()
AppDelegate.shared.onStop()
}
override fun onDestroy() {
super.onDestroy()
AppDelegate.shared.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
AppDelegate.shared.onLowMemory()
}
override fun onRestart() {
logger.info("onRestart")
super.onRestart()
}
override fun onSaveInstanceState(outState: android.os.Bundle): Unit = super.onSaveInstanceState(outState)
override fun onRestoreInstanceState(bundle: android.os.Bundle) {
// Usually you restore your state in onCreate(). It is possible to restore it in onRestoreInstanceState() as well, but not very common. (onRestoreInstanceState() is called after onStart(), whereas onCreate() is called before onStart().
logger.info("onRestoreInstanceState")
super.onRestoreInstanceState(bundle)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: kotlin.Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
logger.info("onRequestPermissionsResult: ${requestCode}")
}
companion object {
}
}
@Composable
internal fun SyncSystemBarsWithTheme() {
val dark = MaterialTheme.colorScheme.background.luminance() < 0.5f
val transparent = AndroidColor.TRANSPARENT
val style = if (dark) {
SystemBarStyle.dark(transparent)
} else {
SystemBarStyle.light(transparent, transparent)
}
val activity = LocalContext.current as? ComponentActivity
DisposableEffect(style) {
activity?.enableEdgeToEdge(
statusBarStyle = style,
navigationBarStyle = style
)
onDispose { }
}
}
@Composable
internal fun PresentationRootView(context: ComposeContext) {
val colorScheme = if (isSystemInDarkTheme()) ColorScheme.dark else ColorScheme.light
PresentationRoot(defaultColorScheme = colorScheme, context = context) { ctx ->
SyncSystemBarsWithTheme()
val contentContext = ctx.content()
Box(modifier = ctx.modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
AppRootView().Compose(context = contentContext)
}
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,11 @@
# This file contains the app distribution configuration
# for the Android half of the Skip app.
# You can find the documentation at https://docs.fastlane.tools
# Load the shared Skip.env properties with the app info
require('dotenv')
Dotenv.load('../../Skip.env')
package_name(ENV['PRODUCT_BUNDLE_IDENTIFIER'].sub("-", "_"))
# Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
json_key_file("fastlane/apikey.json")

View File

@@ -0,0 +1,51 @@
# This file contains the fastlane.tools configuration
# for the Android half of the Skip app.
# You can find the documentation at https://docs.fastlane.tools
# Load the shared Skip.env properties with the app info
require('dotenv')
Dotenv.load '../../Skip.env'
default_platform(:android)
# use the Homebrew gradle rather than expecting a local gradlew
gradle_bin = (ENV['HOMEBREW_PREFIX'] ? ENV['HOMEBREW_PREFIX'] : "/opt/homebrew") + "/bin/gradle"
default_platform(:android)
desc "Build Skip Android App"
lane :build do |options|
build_config = (options[:release] ? "Release" : "Debug")
gradle(
task: "build${build_config}",
gradle_path: gradle_bin,
flags: "--warning-mode none -x lint"
)
end
desc "Test Skip Android App"
lane :test do
gradle(
task: "test",
gradle_path: gradle_bin
)
end
desc "Assemble Skip Android App"
lane :assemble do
gradle(
gradle_path: gradle_bin,
task: "bundleRelease"
)
# sh "your_script.sh"
end
desc "Deploy Skip Android App to Google Play"
lane :release do
assemble
upload_to_play_store(
aab: '../.build/Android/app/outputs/bundle/release/app-release.aab'
)
end

View File

@@ -0,0 +1 @@
A great new app built with Skip!

View File

@@ -0,0 +1 @@
A great new app built with Skip!

View File

@@ -0,0 +1 @@
PediFoods

View File

@@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx4g
android.useAndroidX=true
kotlin.code.style=official

View File

@@ -0,0 +1 @@
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip

View File

@@ -0,0 +1,25 @@
// This gradle project is part of a conventional Skip app project.
pluginManagement {
// Initialize the Skip plugin folder and perform a pre-build for non-Xcode builds
val pluginPath = File.createTempFile("skip-plugin-path", ".tmp")
// overriding outputs for an Android IDE can be done by un-commenting and setting the Xcode path:
//System.setProperty("BUILT_PRODUCTS_DIR", "${System.getProperty("user.home")}/Library/Developer/Xcode/DerivedData/MySkipProject-HASH/Build/Products/Debug-iphonesimulator")
val skipPluginResult = providers.exec {
commandLine("/bin/sh", "-c", "skip plugin --prebuild --package-path '${settings.rootDir.parent}' --plugin-ref '${pluginPath.absolutePath}'")
environment("PATH", "${System.getenv("PATH")}:/opt/homebrew/bin")
}
val skipPluginOutput = skipPluginResult.standardOutput.asText.get()
print(skipPluginOutput)
val skipPluginError = skipPluginResult.standardError.asText.get()
print(skipPluginError)
includeBuild(pluginPath.readText()) {
name = "skip-plugins"
}
}
plugins {
id("skip-plugin") apply true
}