diff --git a/.gitignore b/.gitignore
index 4c9e69e4..d9cc0dcb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,4 @@ ios/fastlane/report.xml
ios/Runner.app.dSYM.zip
/symbols/
+/pub_cache/
diff --git a/android/build/.last_build_id b/android/build/.last_build_id
new file mode 100644
index 00000000..e69de29b
diff --git a/android/settings.gradle b/android/settings.gradle
index 10a012a7..00eeb86f 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -24,4 +24,5 @@ plugins {
id("com.google.gms.google-services") version "4.4.1" apply false
}
-include ":app"
\ No newline at end of file
+include ":app"
+include ':wear'
diff --git a/android/wear/.gitignore b/android/wear/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/android/wear/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/android/wear/build.gradle.kts b/android/wear/build.gradle.kts
new file mode 100644
index 00000000..27d31dbc
--- /dev/null
+++ b/android/wear/build.gradle.kts
@@ -0,0 +1,77 @@
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("org.jetbrains.kotlin.plugin.compose") version "2.0.0" // this version matches your Kotlin version
+
+}
+
+android {
+ namespace = "com.codel1417.tailApp"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.codel1417.tailApp"
+ minSdk = 30
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+ vectorDrawables {
+ useSupportLibrary = true
+ }
+
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+ packaging {
+ resources {
+ excludes += "/META-INF/{AL2.0,LGPL2.1}"
+ }
+ }
+}
+composeCompiler {
+ enableStrongSkippingMode = true
+
+ reportsDestination = layout.buildDirectory.dir("compose_compiler")
+ //stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
+}
+dependencies {
+
+ implementation("com.google.android.gms:play-services-wearable:18.0.0")
+ implementation(platform("androidx.compose:compose-bom:2023.08.00"))
+ implementation("androidx.compose.ui:ui")
+ implementation("androidx.compose.ui:ui-tooling-preview")
+ implementation("androidx.wear.compose:compose-material:1.2.1")
+ implementation("androidx.wear.compose:compose-foundation:1.2.1")
+ implementation("androidx.activity:activity-compose:1.7.2")
+ implementation("androidx.core:core-splashscreen:1.0.1")
+ implementation("androidx.wear.tiles:tiles:1.1.0")
+ implementation("androidx.wear.tiles:tiles-material:1.1.0")
+ implementation("com.google.android.horologist:horologist-compose-tools:0.4.8")
+ implementation("com.google.android.horologist:horologist-tiles:0.4.8")
+ implementation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.1.1")
+ androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
+ androidTestImplementation("androidx.compose.ui:ui-test-junit4")
+ debugImplementation("androidx.compose.ui:ui-tooling")
+ debugImplementation("androidx.compose.ui:ui-test-manifest")
+}
\ No newline at end of file
diff --git a/android/wear/lint.xml b/android/wear/lint.xml
new file mode 100644
index 00000000..44fac75b
--- /dev/null
+++ b/android/wear/lint.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/wear/proguard-rules.pro b/android/wear/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/android/wear/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/android/wear/src/main/AndroidManifest.xml b/android/wear/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..16b10e0c
--- /dev/null
+++ b/android/wear/src/main/AndroidManifest.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/wear/src/main/java/com/codel1417/tailApp/complication/MainComplicationService.kt b/android/wear/src/main/java/com/codel1417/tailApp/complication/MainComplicationService.kt
new file mode 100644
index 00000000..1e059ed6
--- /dev/null
+++ b/android/wear/src/main/java/com/codel1417/tailApp/complication/MainComplicationService.kt
@@ -0,0 +1,41 @@
+package com.codel1417.tailApp.complication
+
+import androidx.wear.watchface.complications.data.ComplicationData
+import androidx.wear.watchface.complications.data.ComplicationType
+import androidx.wear.watchface.complications.data.PlainComplicationText
+import androidx.wear.watchface.complications.data.ShortTextComplicationData
+import androidx.wear.watchface.complications.datasource.ComplicationRequest
+import androidx.wear.watchface.complications.datasource.SuspendingComplicationDataSourceService
+import java.util.Calendar
+
+/**
+ * Skeleton for complication data source that returns short text.
+ */
+class MainComplicationService : SuspendingComplicationDataSourceService() {
+
+ override fun getPreviewData(type: ComplicationType): ComplicationData? {
+ if (type != ComplicationType.SHORT_TEXT) {
+ return null
+ }
+ return createComplicationData("Mon", "Monday")
+ }
+
+ override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData {
+ return when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {
+ Calendar.SUNDAY -> createComplicationData("Sun", "Sunday")
+ Calendar.MONDAY -> createComplicationData("Mon", "Monday")
+ Calendar.TUESDAY -> createComplicationData("Tue", "Tuesday")
+ Calendar.WEDNESDAY -> createComplicationData("Wed", "Wednesday")
+ Calendar.THURSDAY -> createComplicationData("Thu", "Thursday")
+ Calendar.FRIDAY -> createComplicationData("Fri!", "Friday!")
+ Calendar.SATURDAY -> createComplicationData("Sat", "Saturday")
+ else -> throw IllegalArgumentException("too many days")
+ }
+ }
+
+ private fun createComplicationData(text: String, contentDescription: String) =
+ ShortTextComplicationData.Builder(
+ text = PlainComplicationText.Builder(text).build(),
+ contentDescription = PlainComplicationText.Builder(contentDescription).build()
+ ).build()
+}
\ No newline at end of file
diff --git a/android/wear/src/main/java/com/codel1417/tailApp/presentation/theme/Theme.kt b/android/wear/src/main/java/com/codel1417/tailApp/presentation/theme/Theme.kt
new file mode 100644
index 00000000..33f6509c
--- /dev/null
+++ b/android/wear/src/main/java/com/codel1417/tailApp/presentation/theme/Theme.kt
@@ -0,0 +1,17 @@
+package com.codel1417.tailApp.presentation.theme
+
+import androidx.compose.runtime.Composable
+import androidx.wear.compose.material.MaterialTheme
+
+@Composable
+fun _androidTheme(
+ content: @Composable () -> Unit
+) {
+ /**
+ * Empty theme to customize for your app.
+ * See: https://developer.android.com/jetpack/compose/designsystems/custom
+ */
+ MaterialTheme(
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/android/wear/src/main/java/com/codel1417/tailApp/tile/MainTileService.kt b/android/wear/src/main/java/com/codel1417/tailApp/tile/MainTileService.kt
new file mode 100644
index 00000000..51e454a9
--- /dev/null
+++ b/android/wear/src/main/java/com/codel1417/tailApp/tile/MainTileService.kt
@@ -0,0 +1,70 @@
+package com.codel1417.tailApp.tile
+
+import android.content.Context
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.tooling.preview.Devices
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.wear.protolayout.ColorBuilders.argb
+import androidx.wear.protolayout.LayoutElementBuilders
+import androidx.wear.protolayout.ResourceBuilders
+import androidx.wear.protolayout.TimelineBuilders
+import androidx.wear.protolayout.material.Colors
+import androidx.wear.protolayout.material.Text
+import androidx.wear.protolayout.material.Typography
+import androidx.wear.protolayout.material.layouts.PrimaryLayout
+import androidx.wear.tiles.RequestBuilders
+import androidx.wear.tiles.TileBuilders
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+import com.google.android.horologist.compose.tools.LayoutRootPreview
+import com.google.android.horologist.compose.tools.buildDeviceParameters
+import com.google.android.horologist.tiles.SuspendingTileService
+
+private const val RESOURCES_VERSION = "0"
+
+/**
+ * Skeleton for a tile with no images.
+ */
+@OptIn(ExperimentalHorologistApi::class)
+class MainTileService : SuspendingTileService() {
+
+ override suspend fun resourcesRequest(
+ requestParams: RequestBuilders.ResourcesRequest
+ ): ResourceBuilders.Resources {
+ return ResourceBuilders.Resources.Builder().setVersion(RESOURCES_VERSION).build()
+ }
+
+ override suspend fun tileRequest(
+ requestParams: RequestBuilders.TileRequest
+ ): TileBuilders.Tile {
+ val singleTileTimeline = TimelineBuilders.Timeline.Builder().addTimelineEntry(
+ TimelineBuilders.TimelineEntry.Builder().setLayout(
+ LayoutElementBuilders.Layout.Builder().setRoot(tileLayout(this)).build()
+ ).build()
+ ).build()
+
+ return TileBuilders.Tile.Builder().setResourcesVersion(RESOURCES_VERSION)
+ .setTileTimeline(singleTileTimeline).build()
+ }
+}
+
+private fun tileLayout(context: Context): LayoutElementBuilders.LayoutElement {
+ return PrimaryLayout.Builder(buildDeviceParameters(context.resources))
+ .setContent(
+ Text.Builder(context, "Hello World!")
+ .setColor(argb(Colors.DEFAULT.onSurface))
+ .setTypography(Typography.TYPOGRAPHY_CAPTION1)
+ .build()
+ ).build()
+}
+
+@Preview(
+ device = Devices.WEAR_OS_SMALL_ROUND,
+ showSystemUi = true,
+ backgroundColor = 0xff000000,
+ showBackground = true
+)
+@Composable
+fun TilePreview() {
+ LayoutRootPreview(root = tileLayout(LocalContext.current))
+}
\ No newline at end of file
diff --git a/android/wear/src/main/res/drawable-round/tile_preview.png b/android/wear/src/main/res/drawable-round/tile_preview.png
new file mode 100644
index 00000000..474fac4d
Binary files /dev/null and b/android/wear/src/main/res/drawable-round/tile_preview.png differ
diff --git a/android/wear/src/main/res/drawable/splash_icon.xml b/android/wear/src/main/res/drawable/splash_icon.xml
new file mode 100644
index 00000000..7874e83f
--- /dev/null
+++ b/android/wear/src/main/res/drawable/splash_icon.xml
@@ -0,0 +1,27 @@
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
diff --git a/android/wear/src/main/res/drawable/tile_preview.png b/android/wear/src/main/res/drawable/tile_preview.png
new file mode 100644
index 00000000..8cbe3ed5
Binary files /dev/null and b/android/wear/src/main/res/drawable/tile_preview.png differ
diff --git a/android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/android/wear/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/android/wear/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/android/wear/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/android/wear/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/android/wear/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/android/wear/src/main/res/values-round/strings.xml b/android/wear/src/main/res/values-round/strings.xml
new file mode 100644
index 00000000..42f12297
--- /dev/null
+++ b/android/wear/src/main/res/values-round/strings.xml
@@ -0,0 +1,3 @@
+
+ From the Round world,\nHello, %1$s!
+
\ No newline at end of file
diff --git a/android/wear/src/main/res/values/strings.xml b/android/wear/src/main/res/values/strings.xml
new file mode 100644
index 00000000..be2d851e
--- /dev/null
+++ b/android/wear/src/main/res/values/strings.xml
@@ -0,0 +1,10 @@
+
+ The Tail Co
+
+ From the Square world,\nHello, %1$s!
+ Example tile
+ Example complication
+
\ No newline at end of file
diff --git a/android/wear/src/main/res/values/styles.xml b/android/wear/src/main/res/values/styles.xml
new file mode 100644
index 00000000..dbf9c83a
--- /dev/null
+++ b/android/wear/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file