Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ captures
!*.xcworkspace/contents.xcworkspacedata
**/xcshareddata/WorkspaceSettings.xcsettings

# Project exclude paths
# Google Service
composeApp/google-service.json
**/google-service.json
google-service.json

# Project exclude paths
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ plugins {
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.google.services) apply false
alias(libs.plugins.firebase.crashlytics) apply false
alias(libs.plugins.ksp) apply false
}
66 changes: 54 additions & 12 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ kotlin {
}

sourceSets {

// val commonMain by getting {
// kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
// }
//
// // Android
// val androidMain by getting {
// kotlin.srcDir("build/generated/ksp/android/androidDebug/kotlin")
// kotlin.srcDir("build/generated/ksp/android/androidRelease/kotlin")
// }
//
// // iOS
// val iosX64Main by getting {
// kotlin.srcDir("build/generated/ksp/iosX64/iosX64Main/kotlin")
// }
// val iosArm64Main by getting {
// kotlin.srcDir("build/generated/ksp/iosArm64/iosArm64Main/kotlin")
// }
// val iosSimulatorArm64Main by getting {
// kotlin.srcDir("build/generated/ksp/iosSimulatorArm64/iosSimulatorArm64Main/kotlin")
// }

androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
Expand All @@ -60,11 +82,13 @@ kotlin {
implementation(libs.adaptive)
implementation(libs.adaptive.layout)
implementation(libs.adaptive.navigation)

//koin
api(libs.koin.core)
api(libs.koin.annotations)
implementation(libs.koin.core)
implementation(libs.koin.compose)
implementation(libs.koin.compose.viewmodel)
implementation(libs.koin.compose.viewmodel.navigation)
api(libs.koin.annotations)

implementation(libs.ktor.client.core)
implementation(libs.ktor.serialization.kotlinx.json)
Expand All @@ -73,32 +97,42 @@ kotlin {

implementation(libs.bundles.coil)

implementation(libs.kotlinx.datetime)

implementation(libs.androidx.datastore.preferences)

implementation(libs.calf.file.picker)


}
commonTest.dependencies {
implementation(libs.kotlin.test)

implementation(libs.kotlinx.coroutines.test)
implementation(libs.ktor.client.mock)
implementation(libs.koin.test)
}

iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
}

sourceSets.named("commonMain").configure {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}

}

ksp {
//arg("KOIN_USE_COMPOSE_VIEWMODEL","true")
arg("KOIN_CONFIG_CHECK","true")
}

project.tasks.withType(KotlinCompilationTask::class.java).configureEach {
if (name != "kspCommonMainKotlinMetadata") {
dependsOn("kspCommonMainKotlinMetadata")
}
}
//tasks.withType<KotlinCompilationTask<*>>().configureEach {
// if (name != "kspCommonMainKotlinMetadata") {
// dependsOn("kspCommonMainKotlinMetadata")
// }
//}
//
//kotlin.sourceSets.getByName("commonMain") {
// kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
//}


android {
Expand Down Expand Up @@ -132,5 +166,13 @@ android {
dependencies {
debugImplementation(compose.uiTooling)
add("kspCommonMainMetadata", libs.koin.ksp.compiler)

//Android
add("kspAndroid", libs.koin.ksp.compiler)

// iOS (all targets you use)
add("kspIosX64", libs.koin.ksp.compiler)
add("kspIosArm64", libs.koin.ksp.compiler)
add("kspIosSimulatorArm64", libs.koin.ksp.compiler)
}

8 changes: 8 additions & 0 deletions composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET"/>

<!-- For Android 13+ -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- For Android 12 and below -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />

<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
//Firebase.initialize(this)
setContent {
App()
}
Expand Down
12 changes: 10 additions & 2 deletions composeApp/src/androidMain/kotlin/org/example/project/MyApp.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package org.example.project

import android.app.Application
import initKoin
import org.example.project.di.androidModule
import org.example.project.di.initKoin
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger


class MyApp : Application() {
override fun onCreate() {
super.onCreate()
initKoin ()
initKoin {
androidContext(this@MyApp)
androidLogger()
modules(androidModule)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.example.project.data.local.datasource

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map


private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
name = "crafto_preferences"
)

class DataStoreLocalDataSourceImp(
private val context: Context
) : StorageLocalDataSource {

private val dataStore = context.dataStore

override suspend fun saveString(key: String, value: String) {
val preferencesKey = stringPreferencesKey(key)
dataStore.edit { preferences ->
preferences[preferencesKey] = value
}
}

override suspend fun getString(key: String): String? {
val preferencesKey = stringPreferencesKey(key)
return dataStore.data.map { preferences ->
preferences[preferencesKey]
}.first()
}

override suspend fun saveStringSet(key: String, values: Set<String>) {
val preferencesKey = stringSetPreferencesKey(key)
dataStore.edit { preferences ->
preferences[preferencesKey] = values
}
}

override suspend fun getStringSet(key: String): Set<String>? {
val preferencesKey = stringSetPreferencesKey(key)
return dataStore.data.map { preferences ->
preferences[preferencesKey]
}.first()
}

override suspend fun saveLong(key: String, value: Long) {
val preferencesKey = longPreferencesKey(key)
dataStore.edit { preferences ->
preferences[preferencesKey] = value
}
}

override suspend fun getLong(key: String): Long? {
val preferencesKey = longPreferencesKey(key)
return dataStore.data.map { preferences ->
preferences[preferencesKey]
}.first()
}

override suspend fun saveBoolean(key: String, value: Boolean) {
val preferencesKey = booleanPreferencesKey(key)
dataStore.edit { preferences ->
preferences[preferencesKey] = value
}
}

override suspend fun getBoolean(key: String): Boolean? {
val preferencesKey = booleanPreferencesKey(key)
return dataStore.data.map { preferences ->
preferences[preferencesKey]
}.first()
}

override suspend fun remove(key: String) {
dataStore.edit { preferences ->
preferences.remove(stringPreferencesKey(key))
preferences.remove(intPreferencesKey(key))
preferences.remove(longPreferencesKey(key))
preferences.remove(booleanPreferencesKey(key))
preferences.remove(stringSetPreferencesKey(key))
}
}

override suspend fun removeAll() {
dataStore.edit { preferences ->
preferences.clear()
}
}

override suspend fun getAllKeys(): Set<String> {
return dataStore.data.map { preferences ->
preferences.asMap().keys.map { it.name }.toSet()
}.first()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.example.project.di

import org.example.project.data.local.datasource.StorageLocalDataSource
import org.example.project.data.local.datasource.DataStoreLocalDataSourceImp
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module

val androidModule = module {
single<StorageLocalDataSource> {
DataStoreLocalDataSourceImp(androidContext())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.project.util

import android.util.Log

actual object AppLogger {
actual fun e(tag: String, message: String, throwable: Throwable?) {
if (throwable != null) {
Log.e(tag, message, throwable)
} else {
Log.e(tag, message)
}
}

actual fun d(tag: String, message: String) {
Log.d(tag, message)
}

actual fun i(tag: String, message: String) {
Log.i(tag, message)
}
}
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.
32 changes: 32 additions & 0 deletions composeApp/src/commonMain/composeResources/values-ar/string.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,37 @@
<string name="down_arrow">السهم لأسفل</string>


<!-- SetupScreens Strings -->
<string name="user_type">How would you like to use Crafto?</string>
<string name="service_selection">What services do you offer?</string>
<string name="personal_info">Let’s personalize your profile</string>
<string name="portfolio_upload">Show Us Your Work</string>
<string name="identity_verification">Verify Your Identity\n(Optional)</string>
<string name="skip_for_now">I'll Verify Later</string>
<string name="next_step">Next Step</string>

<string name="registration_step_1_description">You can switch roles anytime from your profile.</string>
<string name="registration_step_2_description">Choose your specialties to get relevant job requests. You can change this later.</string>
<string name="registration_step_3_description">We’ll use this to personalize your experience. You can add a profile photo too, or skip for now.</string>
<string name="registration_step_4_description">Add photos of your past work. This helps build trust with customers.</string>
<string name="registration_step_5_description">Uploading your ID helps build trust with customers. Verified craftsmen get more jobs and a special badge on their profile.</string>

<string name="upload_front_of_national_id">Upload front of national ID</string>
<string name="upload_back_of_national_id">Upload back of national ID</string>
<string name="id_card_image">ID card image</string>

<string name="first_name">First name</string>
<string name="last_name">Last name</string>
<string name="phone_number">Phone number</string>
<string name="address">Address</string>

<string name="describe_your_work">Describe your work (optional)</string>
<string name="describe_your_work_hint">You can mention your years of experience, tools you use, or types of jobs you usually handle.</string>
<string name="add_photos">Tap to add photos</string>

<string name="customer">Customer</string>
<string name="customer_description">I need help with a\n problem</string>
<string name="craftsman">Craftsman</string>
<string name="craftsman_description">I offer service</string>

</resources>
31 changes: 31 additions & 0 deletions composeApp/src/commonMain/composeResources/values/string.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,37 @@
<string name="down_arrow">back arrow</string>


<!-- SetupScreens Strings -->
<string name="user_type">How would you like to use Crafto?</string>
<string name="service_selection">What services do you offer?</string>
<string name="personal_info">Let’s personalize your profile</string>
<string name="portfolio_upload">Show Us Your Work</string>
<string name="identity_verification">Verify Your Identity\n(Optional)</string>
<string name="skip_for_now">I'll Verify Later</string>
<string name="next_step">Next Step</string>

<string name="registration_step_1_description">You can switch roles anytime from your profile.</string>
<string name="registration_step_2_description">Choose your specialties to get relevant job requests. You can change this later.</string>
<string name="registration_step_3_description">We’ll use this to personalize your experience. You can add a profile photo too, or skip for now.</string>
<string name="registration_step_4_description">Add photos of your past work. This helps build trust with customers.</string>
<string name="registration_step_5_description">Uploading your ID helps build trust with customers. Verified craftsmen get more jobs and a special badge on their profile.</string>

<string name="upload_front_of_national_id">Upload front of national ID</string>
<string name="upload_back_of_national_id">Upload back of national ID</string>
<string name="id_card_image">ID card image</string>

<string name="first_name">First name</string>
<string name="last_name">Last name</string>
<string name="phone_number">Phone number</string>
<string name="address">Address</string>

<string name="describe_your_work">Describe your work (optional)</string>
<string name="describe_your_work_hint">You can mention your years of experience, tools you use, or types of jobs you usually handle.</string>
<string name="add_photos">Tap to add photos</string>

<string name="customer">Customer</string>
<string name="customer_description">I need help with a\n problem</string>
<string name="craftsman">Craftsman</string>
<string name="craftsman_description">I offer service</string>

</resources>
Loading