Merge pull request 'Data classes and other retrofit logic added' (#12) from dev into main
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Gitea Android Builder / Build (push) Successful in 2m20s
				
			
		
		
	
	
				
					
				
			Reviewed-on: #12
							
								
								
									
										1
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -1,5 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|  |   <component name="GradleMigrationSettings" migrationVersion="1" /> | ||||||
|   <component name="GradleSettings"> |   <component name="GradleSettings"> | ||||||
|     <option name="linkedExternalProjectsSettings"> |     <option name="linkedExternalProjectsSettings"> | ||||||
|       <GradleProjectSettings> |       <GradleProjectSettings> | ||||||
|   | |||||||
| @@ -56,4 +56,10 @@ dependencies { | |||||||
|     androidTestImplementation(libs.androidx.ui.test.junit4) |     androidTestImplementation(libs.androidx.ui.test.junit4) | ||||||
|     debugImplementation(libs.androidx.ui.tooling) |     debugImplementation(libs.androidx.ui.tooling) | ||||||
|     debugImplementation(libs.androidx.ui.test.manifest) |     debugImplementation(libs.androidx.ui.test.manifest) | ||||||
|  |  | ||||||
|  |     implementation(libs.retrofit) | ||||||
|  |     implementation(libs.converter.gson) | ||||||
|  |     implementation(libs.kotlinx.coroutines.android) | ||||||
|  |     implementation(libs.kotlinx.coroutines.core) | ||||||
|  |  | ||||||
| } | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/ic_launcher-playstore.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 36 KiB | 
| @@ -0,0 +1,22 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | import retrofit2.Response | ||||||
|  | import retrofit2.http.GET | ||||||
|  | import retrofit2.http.Query | ||||||
|  |  | ||||||
|  | // Retrofit-API-интерфейс | ||||||
|  | interface CryptoApiService { | ||||||
|  |     // Получение индекса страха и жадности (по умолчанию за 30 дней) | ||||||
|  |     @GET("fng/") | ||||||
|  |     suspend fun getFearAndGreedIndex( | ||||||
|  |         @Query("limit") limit: Int = 30 | ||||||
|  |     ): Response<FearAndGreedResponse> | ||||||
|  |  | ||||||
|  |     // Получение глобальной информации | ||||||
|  |     @GET("v1/global/") | ||||||
|  |     suspend fun getGlobalData(): Response<GlobalResponse> | ||||||
|  |  | ||||||
|  |     // Получение данных Bitcoin | ||||||
|  |     @GET("v1/ticker/bitcoin/") | ||||||
|  |     suspend fun getBitcoinTicker(): Response<TickerResponse> | ||||||
|  | } | ||||||
| @@ -0,0 +1,58 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | //Репозиторий для обработки запросов | ||||||
|  | class CryptoRepository(private val apiService: CryptoApiService) { | ||||||
|  |     /** | ||||||
|  |      * Запрашивает данные для Bitcoin-тикера | ||||||
|  |      */ | ||||||
|  |     suspend fun fetchBitcoinTicker(): TickerResponse? { | ||||||
|  |         return try { | ||||||
|  |             val response = apiService.getBitcoinTicker() | ||||||
|  |             if (response.isSuccessful) { | ||||||
|  |                 response.body() | ||||||
|  |             } else { | ||||||
|  |                 println("Ошибка запроса Bitcoin Ticker: ${response.code()}") | ||||||
|  |                 null | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             println("Exception при получении Bitcoin Ticker: ${e.localizedMessage}") | ||||||
|  |             null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Запрашивает глобальные данные крипторынка | ||||||
|  |      */ | ||||||
|  |     suspend fun fetchGlobalData(): GlobalResponse? { | ||||||
|  |         return try { | ||||||
|  |             val response = apiService.getGlobalData() | ||||||
|  |             if (response.isSuccessful) { | ||||||
|  |                 response.body() | ||||||
|  |             } else { | ||||||
|  |                 println("Ошибка запроса Global Data: ${response.code()}") | ||||||
|  |                 null | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             println("Exception при получении Global Data: ${e.localizedMessage}") | ||||||
|  |             null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Запрашивает индекс страха и жадности за указанный период (по умолчанию 30 дней) | ||||||
|  |      */ | ||||||
|  |     suspend fun fetchFearAndGreedData(limit: Int = 30): FearAndGreedResponse? { | ||||||
|  |         return try { | ||||||
|  |             val response = apiService.getFearAndGreedIndex(limit) | ||||||
|  |             if (response.isSuccessful) { | ||||||
|  |                 response.body() | ||||||
|  |             } else { | ||||||
|  |                 println("Ошибка запроса Fear & Greed Index: ${response.code()}") | ||||||
|  |                 null | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             println("Exception при получении Fear & Greed Index: ${e.localizedMessage}") | ||||||
|  |             null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName | ||||||
|  |  | ||||||
|  | // Обёртка для данных (тут вложенность есть и это API v2, а не v1, поэтому чуть сложнее структура, чем в GlobalResponse.kt) | ||||||
|  | data class FearAndGreedResponse( | ||||||
|  |     @SerializedName("name") | ||||||
|  |     val name: String, | ||||||
|  |     @SerializedName("data") | ||||||
|  |     val dataList: List<FearAndGreedData> | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Сами данные | ||||||
|  | data class FearAndGreedData( | ||||||
|  |     @SerializedName("value") | ||||||
|  |     val value: String, | ||||||
|  |     @SerializedName("value_classification") | ||||||
|  |     val valueClassification: String, | ||||||
|  |     @SerializedName("timestamp") | ||||||
|  |     val timestamp: String, | ||||||
|  |     @SerializedName("time_until_update") | ||||||
|  |     val timeUntilUpdate: String | ||||||
|  | ) | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName | ||||||
|  |  | ||||||
|  | // Обёртка для данных | ||||||
|  | data class GlobalResponse( | ||||||
|  |     val data: GlobalData | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Сами данные | ||||||
|  | data class GlobalData( | ||||||
|  |     @SerializedName("active_cryptocurrencies") val activeCryptocurrencies: String, | ||||||
|  |     @SerializedName("total_market_cap_usd") val totalMarketCapUsd: String, | ||||||
|  |     @SerializedName("total_24h_volume_usd") val total24hVolumeUsd: String | ||||||
|  | ) | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | import retrofit2.Retrofit | ||||||
|  | import retrofit2.converter.gson.GsonConverterFactory | ||||||
|  |  | ||||||
|  | object RetrofitClient { | ||||||
|  |     private const val BASE_URL = "https://api.alternative.me/" | ||||||
|  |  | ||||||
|  |     val apiService: CryptoApiService by lazy { | ||||||
|  |         Retrofit.Builder() | ||||||
|  |             .baseUrl(BASE_URL) | ||||||
|  |             .addConverterFactory(GsonConverterFactory.create()) | ||||||
|  |             .build() | ||||||
|  |             .create(CryptoApiService::class.java) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | package ru.vendetti.bitcoin_summarizer | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName | ||||||
|  |  | ||||||
|  | // Обёртка для данных (тут json-массив с одним элементом, поэтому выглядит так) | ||||||
|  | typealias TickerResponse = List<TickerData> | ||||||
|  |  | ||||||
|  | // Сами данные | ||||||
|  | data class TickerData( | ||||||
|  |     val id: String, | ||||||
|  |     val name: String, | ||||||
|  |     val symbol: String, | ||||||
|  |     val rank: String, | ||||||
|  |     @SerializedName("price_usd") val priceUsd: String, | ||||||
|  |     @SerializedName("price_btc") val priceBtc: String, | ||||||
|  |     @SerializedName("24h_volume_usd") val volume24hUsd: String, | ||||||
|  |     @SerializedName("market_cap_usd") val marketCapUsd: String, | ||||||
|  |     @SerializedName("available_supply") val availableSupply: String, | ||||||
|  |     @SerializedName("total_supply") val totalSupply: String, | ||||||
|  |     @SerializedName("max_supply") val maxSupply: String?, | ||||||
|  |     @SerializedName("percent_change_1h") val percentChange1h: String, | ||||||
|  |     @SerializedName("percent_change_24h") val percentChange24h: String, | ||||||
|  |     @SerializedName("percent_change_7d") val percentChange7d: String, | ||||||
|  |     @SerializedName("last_updated") val lastUpdated: String | ||||||
|  | ) | ||||||
							
								
								
									
										6
									
								
								app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
									
									
									
									
									
										Normal 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="@color/ic_launcher_background"/> | ||||||
|  |     <foreground android:drawable="@mipmap/ic_launcher_foreground"/> | ||||||
|  |     <monochrome android:drawable="@mipmap/ic_launcher_foreground"/> | ||||||
|  | </adaptive-icon> | ||||||
							
								
								
									
										6
									
								
								app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
									
									
									
									
									
										Normal 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="@color/ic_launcher_background"/> | ||||||
|  |     <foreground android:drawable="@mipmap/ic_launcher_foreground"/> | ||||||
|  |     <monochrome android:drawable="@mipmap/ic_launcher_foreground"/> | ||||||
|  | </adaptive-icon> | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |  | ||||||
|     <background android:drawable="@drawable/ic_launcher_background" /> |  | ||||||
|     <foreground android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
|     <monochrome android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
| </adaptive-icon> |  | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |  | ||||||
|     <background android:drawable="@drawable/ic_launcher_background" /> |  | ||||||
|     <foreground android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
|     <monochrome android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
| </adaptive-icon> |  | ||||||
| Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.3 KiB | 
| Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.2 KiB | 
| Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.1 KiB | 
| Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 5.5 KiB | 
| Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.0 KiB | 
| Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 8.3 KiB | 
| Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 6.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.7 KiB | 
| Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										4
									
								
								app/src/main/res/values/ic_launcher_background.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,4 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <resources> | ||||||
|  |     <color name="ic_launcher_background">#FFFFFF</color> | ||||||
|  | </resources> | ||||||
| @@ -1,16 +1,21 @@ | |||||||
| [versions] | [versions] | ||||||
| agp = "8.8.1" | agp = "8.8.1" | ||||||
|  | converterGson = "2.9.0" | ||||||
| kotlin = "2.0.0" | kotlin = "2.0.0" | ||||||
| coreKtx = "1.10.1" | coreKtx = "1.10.1" | ||||||
| junit = "4.13.2" | junit = "4.13.2" | ||||||
| junitVersion = "1.1.5" | junitVersion = "1.1.5" | ||||||
| espressoCore = "3.5.1" | espressoCore = "3.5.1" | ||||||
|  | kotlinxCoroutinesAndroid = "1.7.1" | ||||||
|  | kotlinxCoroutinesCore = "1.7.1" | ||||||
| lifecycleRuntimeKtx = "2.6.1" | lifecycleRuntimeKtx = "2.6.1" | ||||||
| activityCompose = "1.8.0" | activityCompose = "1.8.0" | ||||||
| composeBom = "2024.04.01" | composeBom = "2024.04.01" | ||||||
|  | retrofit = "2.9.0" | ||||||
|  |  | ||||||
| [libraries] | [libraries] | ||||||
| androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } | androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } | ||||||
|  | converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" } | ||||||
| junit = { group = "junit", name = "junit", version.ref = "junit" } | junit = { group = "junit", name = "junit", version.ref = "junit" } | ||||||
| androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } | androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } | ||||||
| androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } | androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } | ||||||
| @@ -24,6 +29,9 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin | |||||||
| androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } | androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } | ||||||
| androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } | androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } | ||||||
| androidx-material3 = { group = "androidx.compose.material3", name = "material3" } | androidx-material3 = { group = "androidx.compose.material3", name = "material3" } | ||||||
|  | kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutinesAndroid" } | ||||||
|  | kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesCore" } | ||||||
|  | retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } | ||||||
|  |  | ||||||
| [plugins] | [plugins] | ||||||
| android-application = { id = "com.android.application", version.ref = "agp" } | android-application = { id = "com.android.application", version.ref = "agp" } | ||||||
|   | |||||||