Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
marcprux committed Feb 10, 2025
0 parents commit 7f0ddb6
Show file tree
Hide file tree
Showing 96 changed files with 2,889 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/app-name-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This is a GitHub workflow that will build the Skip app whenever
# a push or release tag is made. In addition, various secrets can be
# enabled for the repository that will automatically publish
# releases to the Apple App Store and/or Google Play Store.
#
# See the documentation at https://skip.tools/docs for more details.
name: app-name-app
on:
push:
branches: '*'
tags: "[0-9]+.[0-9]+.[0-9]+"
# example of daily scheduled build
#schedule:
#- cron: '0 12 * * *'
workflow_dispatch:
pull_request:

permissions:
contents: write
id-token: write
attestations: write
jobs:
call-workflow:
uses: skiptools/actions/.github/workflows/skip-app.yml@main
secrets:
# These optional secrets enable the Android app to be signed
KEYSTORE_JKS: ${{ secrets.KEYSTORE_JKS }}
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}

# This secret enables the Android app to be uploaded to the Play Store
GOOGLE_PLAY_APIKEY: ${{ secrets.GOOGLE_PLAY_APIKEY }}

# These optional secrets enable the iOS app to be signed
APPLE_CERTIFICATES_P12: ${{ secrets.APPLE_CERTIFICATES_P12 }}
APPLE_CERTIFICATES_P12_PASSWORD: ${{ secrets.APPLE_CERTIFICATES_P12_PASSWORD }}

# This secret enables the iOS app to be uploaded to the App Store
APPLE_APPSTORE_APIKEY: ${{ secrets.APPLE_APPSTORE_APIKEY }}
82 changes: 82 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
## User settings

# vi
.*.swp
.*.swo

# macOS
.DS_Store

# gradle properties
local.properties
.gradle/
.android/
.kotlin/
Android/app/keystore.jks
Android/app/keystore.properties

xcodebuild*.log

default.profraw
*.mobileprovision
*.cer


# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
.swiftpm
.build/
build/
DerivedData/
xcuserdata/
xcodebuild*.log
.idea/

*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcscmblueprint
*.xccheckout

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
Packages/
Package.pins
Package.resolved
#*.xcodeproj

Carthage/Build/

# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

**/fastlane/apikey.json
**/fastlane/report.xml
**/fastlane/README.md
**/fastlane/Preview.html
**/fastlane/screenshots/**/*.png
**/fastlane/metadata/android/*/images/**/*.png
**/fastlane/test_output
71 changes: 71 additions & 0 deletions Android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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 {
}

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())
}
kotlinOptions {
jvmTarget = libs.versions.jvm.get().toString()
}
packaging {
jniLibs {
keepDebugSymbols.add("**/*.so")
pickFirsts.add("**/*.so")
}
}

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 = PRODUCT_BUNDLE_IDENTIFIER
// versionCode = CURRENT_PROJECT_VERSION
// versionName = MARKETING_VERSION
}

buildFeatures {
buildConfig = true
}

lintOptions {
disable.add("Instantiatable")
}

// default signing configuration tries to load from keystore.properties
signingConfigs {
val keystorePropertiesFile = file("keystore.properties")
if (keystorePropertiesFile.isFile) {
create("release") {
val keystoreProperties = Properties()
keystoreProperties.load(keystorePropertiesFile.inputStream())
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("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")
}
}
}
6 changes: 6 additions & 0 deletions Android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-keeppackagenames **
-keep class skip.** { *; }
-keep class kotlin.jvm.functions.** {*;}
-keep class com.sun.jna.** { *; }
-keep class * implements com.sun.jna.** { *; }
-keep class app.name.** { *; }
30 changes: 30 additions & 0 deletions Android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -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>
127 changes: 127 additions & 0 deletions Android/app/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package app.name

import skip.lib.*
import skip.model.*
import skip.foundation.*
import skip.ui.*

import android.Manifest
import android.app.Application
import androidx.activity.enableEdgeToEdge
import androidx.activity.compose.setContent
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.SideEffect
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.core.app.ActivityCompat

internal val logger: SkipLogger = SkipLogger(subsystem = "app.name", category = "AppName")

/// 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)
}

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) }
}
}

// 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 onSaveInstanceState(bundle: android.os.Bundle): Unit = super.onSaveInstanceState(bundle)

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 onRestart() {
logger.info("onRestart")
super.onRestart()
}

override fun onStart() {
logger.info("onStart")
super.onStart()
}

override fun onResume() {
logger.info("onResume")
super.onResume()
}

override fun onPause() {
logger.info("onPause")
super.onPause()
}

override fun onStop() {
logger.info("onStop")
super.onStop()
}

override fun onDestroy() {
logger.info("onDestroy")
super.onDestroy()
}

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 PresentationRootView(context: ComposeContext) {
val colorScheme = if (isSystemInDarkTheme()) ColorScheme.dark else ColorScheme.light
PresentationRoot(defaultColorScheme = colorScheme, context = context) { ctx ->
val contentContext = ctx.content()
Box(modifier = ctx.modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
RootView().Compose(context = contentContext)
}
}
}
6 changes: 6 additions & 0 deletions Android/app/src/main/res/mipmap-anydpi/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions Android/fastlane/Appfile
Original file line number Diff line number Diff line change
@@ -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'])

# Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
json_key_file("fastlane/apikey.json")
Loading

0 comments on commit 7f0ddb6

Please sign in to comment.