@@ -1,21 +1,33 @@
 
			
		
	
		
		
			
				
					
					package  ru.vendetti.bitcoin_summarizer package  ru.vendetti.bitcoin_summarizer  
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					import  android.annotation.SuppressLint import  android.annotation.SuppressLint  
			
		
	
		
		
			
				
					
					import  android.content.Context  
			
		
	
		
		
			
				
					
					import  android.content.pm.PackageManager  
			
		
	
		
		
			
				
					
					import  android.os.Bundle import  android.os.Bundle  
			
		
	
		
		
			
				
					
					import  android.util.Log  
			
		
	
		
		
			
				
					
					import  android.view.LayoutInflater import  android.view.LayoutInflater  
			
		
	
		
		
			
				
					
					import  android.view.View import  android.view.View  
			
		
	
		
		
			
				
					
					import  android.view.ViewGroup import  android.view.ViewGroup  
			
		
	
		
		
			
				
					
					import  androidx.activity.compose.rememberLauncherForActivityResult  
			
		
	
		
		
			
				
					
					import  androidx.activity.result.contract.ActivityResultContracts  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.background import  androidx.compose.foundation.background  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.Box import  androidx.compose.foundation.layout.Box  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.Column import  androidx.compose.foundation.layout.Column  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.Spacer import  androidx.compose.foundation.layout.Spacer  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.fillMaxSize  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.fillMaxWidth  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.height import  androidx.compose.foundation.layout.height  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.padding import  androidx.compose.foundation.layout.padding  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.layout.wrapContentSize  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.rememberScrollState import  androidx.compose.foundation.rememberScrollState  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.shape.RoundedCornerShape  
			
		
	
		
		
			
				
					
					import  androidx.compose.foundation.verticalScroll import  androidx.compose.foundation.verticalScroll  
			
		
	
		
		
			
				
					
					import  androidx.compose.material.icons.Icons import  androidx.compose.material.icons.Icons  
			
		
	
		
		
			
				
					
					import  androidx.compose.material.icons.filled.Menu import  androidx.compose.material.icons.filled.Menu  
			
		
	
		
		
			
				
					
					import  androidx.compose.material.icons.filled.MoreVert  import  androidx.compose.material3.AlertDialog   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					import  androidx.compose.material3.ButtonColors  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.ButtonDefaults  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.Card  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.CenterAlignedTopAppBar import  androidx.compose.material3.CenterAlignedTopAppBar  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.DrawerValue import  androidx.compose.material3.DrawerValue  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.ExperimentalMaterial3Api import  androidx.compose.material3.ExperimentalMaterial3Api  
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -23,11 +35,10 @@ import androidx.compose.material3.HorizontalDivider
 
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.Icon import  androidx.compose.material3.Icon  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.IconButton import  androidx.compose.material3.IconButton  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.MaterialTheme import  androidx.compose.material3.MaterialTheme  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.MediumTopAppBar  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.ModalDrawerSheet  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.ModalNavigationDrawer import  androidx.compose.material3.ModalNavigationDrawer  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.Scaffold import  androidx.compose.material3.Scaffold  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.Text import  androidx.compose.material3.Text  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.TextButton  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.TopAppBarDefaults import  androidx.compose.material3.TopAppBarDefaults  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.rememberDrawerState import  androidx.compose.material3.rememberDrawerState  
			
		
	
		
		
			
				
					
					import  androidx.compose.material3.rememberTopAppBarState import  androidx.compose.material3.rememberTopAppBarState  
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -42,13 +53,19 @@ import androidx.compose.runtime.setValue
 
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.Alignment import  androidx.compose.ui.Alignment  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.Modifier import  androidx.compose.ui.Modifier  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.graphics.Color import  androidx.compose.ui.graphics.Color  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.graphics.vector.ImageVector  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.input.nestedscroll.nestedScroll import  androidx.compose.ui.input.nestedscroll.nestedScroll  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.platform.ComposeView import  androidx.compose.ui.platform.ComposeView  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.platform.LocalContext  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.text.style.TextAlign  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.text.style.TextOverflow import  androidx.compose.ui.text.style.TextOverflow  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.tooling.preview.Preview import  androidx.compose.ui.tooling.preview.Preview  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.unit.dp import  androidx.compose.ui.unit.dp  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.unit.sp import  androidx.compose.ui.unit.sp  
			
		
	
		
		
			
				
					
					import  androidx.compose.ui.window.Dialog  
			
		
	
		
		
			
				
					
					import  androidx.core.content.ContextCompat  
			
		
	
		
		
			
				
					
					import  androidx.fragment.app.Fragment import  androidx.fragment.app.Fragment  
			
		
	
		
		
			
				
					
					import  com.google.gson.Gson  
			
		
	
		
		
			
				
					
					import  com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost import  com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost  
			
		
	
		
		
			
				
					
					import  com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLabelComponent import  com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLabelComponent  
			
		
	
		
		
			
				
					
					import  com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLineComponent import  com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLineComponent  
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -80,6 +97,9 @@ import kotlinx.coroutines.launch
 
			
		
	
		
		
			
				
					
					import  ru.vendetti.bitcoin_summarizer.ui.theme.BitcoinSummarizerTheme import  ru.vendetti.bitcoin_summarizer.ui.theme.BitcoinSummarizerTheme  
			
		
	
		
		
			
				
					
					import  ru.vendetti.bitcoin_summarizer.ui.theme.Flame import  ru.vendetti.bitcoin_summarizer.ui.theme.Flame  
			
		
	
		
		
			
				
					
					import  ru.vendetti.bitcoin_summarizer.ui.theme.Green2 import  ru.vendetti.bitcoin_summarizer.ui.theme.Green2  
			
		
	
		
		
			
				
					
					import  java.io.FileInputStream  
			
		
	
		
		
			
				
					
					import  java.io.FileOutputStream  
			
		
	
		
		
			
				
					
					import  java.lang.StringBuilder  
			
		
	
		
		
			
				
					
					import  java.text.DecimalFormat import  java.text.DecimalFormat  
			
		
	
		
		
			
				
					
					import  java.time.Instant import  java.time.Instant  
			
		
	
		
		
			
				
					
					import  java.time.format.DateTimeFormatter import  java.time.format.DateTimeFormatter  
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -102,11 +122,51 @@ class CryptoFragment: Fragment() {
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					@Composable  
			
		
	
		
		
			
				
					
					fun  ShowAlertDialog (  
			
		
	
		
		
			
				
					
					    onDismissRequest :  ( )  ->  Unit , 
 
			
		
	
		
		
			
				
					
					    onConfirmation :  ( )  ->  Unit , 
 
			
		
	
		
		
			
				
					
					    dialogTitle :  String , 
 
			
		
	
		
		
			
				
					
					    dialogText :  String , 
 
			
		
	
		
		
			
				
					
					)  {  
			
		
	
		
		
			
				
					
					    AlertDialog ( 
 
			
		
	
		
		
			
				
					
					        icon  =  { } , 
 
			
		
	
		
		
			
				
					
					        title  =  { 
 
			
		
	
		
		
			
				
					
					            Text ( text  =  dialogTitle ) 
 
			
		
	
		
		
			
				
					
					        } , 
 
			
		
	
		
		
			
				
					
					        text  =  { 
 
			
		
	
		
		
			
				
					
					            Text ( text  =  dialogText ) 
 
			
		
	
		
		
			
				
					
					        } , 
 
			
		
	
		
		
			
				
					
					        onDismissRequest  =  { 
 
			
		
	
		
		
			
				
					
					            onDismissRequest ( ) 
 
			
		
	
		
		
			
				
					
					        } , 
 
			
		
	
		
		
			
				
					
					        confirmButton  =  { } , 
 
			
		
	
		
		
			
				
					
					        dismissButton  =  { 
 
			
		
	
		
		
			
				
					
					            TextButton ( 
 
			
		
	
		
		
			
				
					
					                onClick  =  { 
 
			
		
	
		
		
			
				
					
					                    onDismissRequest ( ) 
 
			
		
	
		
		
			
				
					
					                } 
 
			
		
	
		
		
			
				
					
					            )  { 
 
			
		
	
		
		
			
				
					
					                Text ( 
 
			
		
	
		
		
			
				
					
					                    text  =  " Окей " , 
 
			
		
	
		
		
			
				
					
					                    color  =  MaterialTheme . colorScheme . onPrimary 
 
			
		
	
		
		
			
				
					
					                ) 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					        } , 
 
			
		
	
		
		
			
				
					
					        containerColor  =  MaterialTheme . colorScheme . primary , 
 
			
		
	
		
		
			
				
					
					        titleContentColor  =  MaterialTheme . colorScheme . onPrimary , 
 
			
		
	
		
		
			
				
					
					        textContentColor  =  MaterialTheme . colorScheme . onPrimary , 
 
			
		
	
		
		
			
				
					
					    ) 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					@SuppressLint ( " MutableCollectionMutableState " ,  " SimpleDateFormat " ) @SuppressLint ( " MutableCollectionMutableState " ,  " SimpleDateFormat " )  
			
		
	
		
		
			
				
					
					@OptIn ( ExperimentalMaterial3Api :: class ) @OptIn ( ExperimentalMaterial3Api :: class )  
			
		
	
		
		
			
				
					
					@Preview @Preview  
			
		
	
		
		
			
				
					
					@Composable @Composable  
			
		
	
		
		
			
				
					
					fun  CryptoComposable ( )  { fun  CryptoComposable ( )  {  
			
		
	
		
		
			
				
					
					    val  openAlertDialog1  =  remember  {  mutableStateOf ( false )  } 
 
			
		
	
		
		
			
				
					
					    val  openAlertDialog2  =  remember  {  mutableStateOf ( false )  } 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    // Создаем репозиторий для работы с  
    // Создаем репозиторий для работы с  
 
			
		
	
		
		
			
				
					
					val  cryptoRepository  =  remember  {  CryptoRepository ( RetrofitClient . apiService )  } val  cryptoRepository  =  remember  {  CryptoRepository ( RetrofitClient . apiService )  }  
			
		
	
		
		
			
				
					
					    // Состояния для хранения результатов запросов 
    // Состояния для хранения результатов запросов 
 
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -116,8 +176,36 @@ fun CryptoComposable() {
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    var  fearGreedIndexDaysCount  by  remember  {  mutableIntStateOf ( 30 )  } 
    var  fearGreedIndexDaysCount  by  remember  {  mutableIntStateOf ( 30 )  } 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    val  gson  =  Gson ( ) 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    val  context  =  LocalContext . current 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    when  { 
 
			
		
	
		
		
			
				
					
					        openAlertDialog1 . value  ->  { 
 
			
		
	
		
		
			
				
					
					            ShowAlertDialog ( 
 
			
		
	
		
		
			
				
					
					                onDismissRequest  =  { openAlertDialog1 . value  =  false } , 
 
			
		
	
		
		
			
				
					
					                onConfirmation  =  { } , 
 
			
		
	
		
		
			
				
					
					                dialogTitle  =  " Внимание! " , 
 
			
		
	
		
		
			
				
					
					                dialogText  =  " Отсутствует интернет-подключение, загружаю сохраненные данные.  "  + 
 
			
		
	
		
		
			
				
					
					                        " "  + 
 
			
		
	
		
		
			
				
					
					                        " Обратите внимание, что данные могут быть неактуальными. " , 
 
			
		
	
		
		
			
				
					
					            ) 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					        openAlertDialog2 . value  ->  { 
 
			
		
	
		
		
			
				
					
					            ShowAlertDialog ( 
 
			
		
	
		
		
			
				
					
					                onDismissRequest  =  { 
 
			
		
	
		
		
			
				
					
					                    openAlertDialog2 . value  =  false 
 
			
		
	
		
		
			
				
					
					                    App . INSTANCE . router . exit ( ) 
 
			
		
	
		
		
			
				
					
					                                   } , 
 
			
		
	
		
		
			
				
					
					                onConfirmation  =  { } , 
 
			
		
	
		
		
			
				
					
					                dialogTitle  =  " Внимание! " , 
 
			
		
	
		
		
			
				
					
					                dialogText  =  " При первом подключении необходимо подключение к интернету! " , 
 
			
		
	
		
		
			
				
					
					            ) 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					    // Запускаем корутину для выполнения сетевых запросов 
    // Запускаем корутину для выполнения сетевых запросов 
 
			
		
	
		
		
			
				
					
					LaunchedEffect ( fearGreedIndexDaysCount )  { LaunchedEffect ( fearGreedIndexDaysCount ,  context {  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					        try  { 
        try  { 
 
			
		
	
		
		
			
				
					
					            // Запрос Bitcoin Ticker 
            // Запрос Bitcoin Ticker 
 
			
		
	
		
		
			
				
					
					val  tickerResponse  =  cryptoRepository . fetchBitcoinTicker ( ) val  tickerResponse  =  cryptoRepository . fetchBitcoinTicker ( )  
			
		
	
	
		
		
			
				
					
					
						
					 
					@@ -131,31 +219,53 @@ fun CryptoComposable() {
 
			
		
	
		
		
			
				
					
					val  fearResponse  =  cryptoRepository . fetchFearAndGreedData ( fearGreedIndexDaysCount ) val  fearResponse  =  cryptoRepository . fetchFearAndGreedData ( fearGreedIndexDaysCount )  
			
		
	
		
		
			
				
					
					            fearGreedDataList  =  fearResponse ?. dataList  as  ArrayList < FearAndGreedData > 
            fearGreedDataList  =  fearResponse ?. dataList  as  ArrayList < FearAndGreedData > 
 
			
		
	
		
		
			
				
					
					            fearGreedDataList . reverse ( ) 
            fearGreedDataList . reverse ( ) 
 
			
		
	
		
		
			
				
					
					        } catch  ( e :  Exception )  { 
 
			
				
				
			
		
	
		
		
			
				
					
					            bitcoinTicker  =  TickerData ( 
            // *** Сохраняем на диск *** 
 
			
				
				
			
		
	
		
		
			
				
					
					                id  =  " " ,  
// 1) С б о р   
			
				
				
			
		
	
		
		
			
				
					
					                name  =  " "  , 
val  fullStatistics  =  StatisticsFull (  
			
				
				
			
		
	
		
		
			
				
					
					                symbol  =  " " , 
                FGI _list  =  fearGreedDataList , 
 
			
				
				
			
		
	
		
		
			
				
					
					                rank  =  " " , 
                TickerData  =  bitcoinTicker , 
 
			
				
				
			
		
	
		
		
			
				
					
					                priceUsd  =  " " , 
                GlobalData  =  globalData , 
 
			
				
				
			
		
	
		
		
			
				
					
					                priceBtc  =  " " , 
 
			
		
	
		
		
			
				
					
					                volume24hUsd  =  " " , 
 
			
		
	
		
		
			
				
					
					                marketCapUsd  =  " " , 
 
			
		
	
		
		
			
				
					
					                availableSupply  =  " " , 
 
			
		
	
		
		
			
				
					
					                totalSupply  =  " " , 
 
			
		
	
		
		
			
				
					
					                maxSupply  =  " " , 
 
			
		
	
		
		
			
				
					
					                percentChange1h  =  " " , 
 
			
		
	
		
		
			
				
					
					                percentChange24h  =  " " , 
 
			
		
	
		
		
			
				
					
					                percentChange7d  =  " " , 
 
			
		
	
		
		
			
				
					
					                lastUpdated  =  " " 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					            ) 
            ) 
 
			
		
	
		
		
			
				
					
					            globalData  =  GlobalResponse ( 
 
			
				
				
			
		
	
		
		
			
				
					
					                activeCryptocurrencies  =  " " ,  
            // 2) Перевод класса в json-строку 
 
			
				
				
			
		
	
		
		
			
				
					
					                totalMarketCapUsd  =  " "  , 
val  statisticsJsonString  =  gson . toJson ( fullStatistics )  
			
				
				
			
		
	
		
		
			
				
					
					                total24hVolumeUsd  =  " " , 
 
			
				
				
			
		
	
		
		
			
				
					
					                bitcoinPercentageOfMarketCap  =  " "  
            // 3) Сохранение в файл во внутреннем хранилище 
 
			
				
				
			
		
	
		
		
			
				
					
					            ) 
val  fos :  FileOutputStream  =  
			
				
				
			
		
	
		
		
			
				
					
					            fearGreedDataList  =  ArrayList < FearAndGreedData > ( ) 
                context . openFileOutput ( " statistics.txt " ,  Context . MODE _PRIVATE  ) 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					            fos . write ( statisticsJsonString . toByteArray ( ) ) 
 
			
		
	
		
		
			
				
					
					            fos . flush ( ) 
 
			
		
	
		
		
			
				
					
					            fos . close ( ) 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					        catch  ( e :  Exception )  { 
 
			
		
	
		
		
			
				
					
					            try  { 
 
			
		
	
		
		
			
				
					
					                // *** Загрузка данных из файла *** 
 
			
		
	
		
		
			
				
					
					// 1) Получение строки из файла  
			
		
	
		
		
			
				
					
					val  fis :  FileInputStream  =  
			
		
	
		
		
			
				
					
					                    context . openFileInput ( " statistics.txt " ) 
 
			
		
	
		
		
			
				
					
					                var  a :  Int 
 
			
		
	
		
		
			
				
					
					                val  temp  =  StringBuilder ( ) 
 
			
		
	
		
		
			
				
					
					                while  ( fis . read ( ) . also  {  a  =  it  }  !=  - 1 )  { 
 
			
		
	
		
		
			
				
					
					                    temp . append ( a . toChar ( ) ) 
 
			
		
	
		
		
			
				
					
					                } 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					                // Показ предупреждения. 
 
			
		
	
		
		
			
				
					
					openAlertDialog1 . value  =  true  
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					                val  statisticsJsonString  =  temp . toString ( ) 
 
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					                // 2) Перевод строки в класс 
 
			
		
	
		
		
			
				
					
					val  statisticsFull  =  gson . fromJson ( statisticsJsonString ,  StatisticsFull :: class . java )  
			
		
	
		
		
			
				
					
					 
			
		
	
		
		
			
				
					
					                // 3) Распределение данных по переменным 
 
			
		
	
		
		
			
				
					
					bitcoinTicker  =  statisticsFull . TickerData  
			
		
	
		
		
			
				
					
					                globalData  =  statisticsFull . GlobalData 
 
			
		
	
		
		
			
				
					
					                fearGreedDataList  =  statisticsFull . FGI _list 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					            catch  ( e :  Exception )  { 
 
			
		
	
		
		
			
				
					
					                openAlertDialog2 . value  =  true 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					        } 
        } 
 
			
		
	
		
		
			
				
					
					    } 
    }