diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/recyclerview/weather/WeekWeatherAdapter.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/recyclerview/weather/WeekWeatherAdapter.kt index 1e051d68..97c2c4f7 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/recyclerview/weather/WeekWeatherAdapter.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/adapter/recyclerview/weather/WeekWeatherAdapter.kt @@ -5,16 +5,18 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.project.how.R -import com.project.how.data_class.dto.weather.GetWeeklyWeathersResponseElement +import com.project.how.data_class.dto.country.weather.GetWeeklyWeathersResponseElement import com.project.how.databinding.WeekWeatherItemBinding +import kotlin.math.roundToInt -class WeekWeatherAdapter(private val data : List) +class WeekWeatherAdapter(private var data : List) : RecyclerView.Adapter() { inner class ViewHolder(val binding: WeekWeatherItemBinding) : RecyclerView.ViewHolder(binding.root){ fun bind(data: GetWeeklyWeathersResponseElement){ - binding.week.text = data.date - binding.temp.text = data.temp + val temp = data.temp.toDouble().roundToInt() + binding.week.text = data.date.removeRange(0,11) + binding.temp.text = "$temp℃" Glide.with(binding.root) .load(data.iconUrl) .error(R.drawable.icon_question) @@ -38,4 +40,9 @@ class WeekWeatherAdapter(private val data : List){ + data = newData + notifyDataSetChanged() + } + } \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/GetCountryInfoRequest.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/GetCountryInfoRequest.kt new file mode 100644 index 00000000..f44d8628 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/GetCountryInfoRequest.kt @@ -0,0 +1,7 @@ +package com.project.how.data_class.dto.country + +import com.google.gson.annotations.SerializedName + +data class GetCountryInfoRequest( + @SerializedName("country") val country : String +) diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetCurrentWeatherResponse.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetCurrentWeatherResponse.kt new file mode 100644 index 00000000..cd2c2e22 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetCurrentWeatherResponse.kt @@ -0,0 +1,15 @@ +package com.project.how.data_class.dto.country.weather + +import com.google.gson.annotations.SerializedName + +data class GetCurrentWeatherResponse ( + val main: String, + val description: String, + val temp: String, + val localTime: String, + val iconUrl: String, + @SerializedName("temp_min") + val tempMin: String, + @SerializedName("temp_max") + val tempMax: String +) \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetWeeklyWeathersResponse.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetWeeklyWeathersResponse.kt new file mode 100644 index 00000000..64b80fc9 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/data_class/dto/country/weather/GetWeeklyWeathersResponse.kt @@ -0,0 +1,14 @@ +package com.project.how.data_class.dto.country.weather + +import com.google.gson.annotations.SerializedName + +typealias GetWeeklyWeathersResponse = ArrayList + +data class GetWeeklyWeathersResponseElement ( + @SerializedName("date") + val date: String, + @SerializedName("temp") + val temp: String, + @SerializedName("iconUrl") + val iconUrl: String +) diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/interface_af/OnDateTimeListener.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/interface_af/OnDateTimeListener.kt index e69dd99b..8f37551c 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/interface_af/OnDateTimeListener.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/interface_af/OnDateTimeListener.kt @@ -3,5 +3,5 @@ package com.project.how.interface_af import com.project.how.data_class.recyclerview.DaysSchedule interface OnDateTimeListener { - fun onSaveDate(d : DaysSchedule, date : String, position: Int) + fun onSaveDate(d: DaysSchedule, selectedDate: String, changedDate: String, position: Int) } \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/model/CountryRepository.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/model/CountryRepository.kt new file mode 100644 index 00000000..dc348927 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/model/CountryRepository.kt @@ -0,0 +1,24 @@ +package com.project.how.model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.project.how.data_class.dto.country.weather.GetCurrentWeatherResponse +import com.project.how.data_class.dto.country.weather.GetWeeklyWeathersResponse + +class CountryRepository { + private var _currentWeatherLiveData : MutableLiveData = MutableLiveData() + private var _weeklyWeathersLiveData : MutableLiveData = MutableLiveData() + val currentWeatherLiveData : LiveData + get() = _currentWeatherLiveData + val weeklyWeathersLiveData : LiveData + get() = _weeklyWeathersLiveData + + fun getCurrentWeather(data : GetCurrentWeatherResponse){ + _currentWeatherLiveData.postValue(data) + } + + fun getWeeklyWeathers(data : GetWeeklyWeathersResponse){ + _weeklyWeathersLiveData.postValue(data) + } + +} \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/model/ScheduleRepository.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/model/ScheduleRepository.kt index 1bb70761..51781826 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/model/ScheduleRepository.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/model/ScheduleRepository.kt @@ -22,12 +22,6 @@ import java.time.temporal.ChronoUnit import java.util.Calendar class ScheduleRepository { - val today = Calendar.getInstance().apply { - set(Calendar.HOUR_OF_DAY, 0) - set(Calendar.MINUTE, 0) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - }.time.time private val _nearScheduleDayLiveData : MutableLiveData = MutableLiveData() private val _scheduleLiveData : MutableLiveData = MutableLiveData() private val _scheduleListLiveData : MutableLiveData = MutableLiveData() @@ -63,7 +57,7 @@ class ScheduleRepository { aiSchedule.country, aiSchedule.startDate, aiSchedule.endDate, - 0, + aiSchedule.budget, getDailySchedule(aiSchedule.dailySchedule) ) ) diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/CountryService.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/CountryService.kt new file mode 100644 index 00000000..4bdd8a02 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/CountryService.kt @@ -0,0 +1,26 @@ +package com.project.how.network.api_interface + +import com.project.how.data_class.dto.country.GetCountryInfoRequest +import com.project.how.data_class.dto.country.GetCountryLocationResponse +import com.project.how.data_class.dto.country.weather.GetCurrentWeatherResponse +import com.project.how.data_class.dto.country.weather.GetWeeklyWeathersResponse +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.POST + +interface CountryService { + @POST("countries/locations") + fun getCountryLocation( + @Body country : GetCountryInfoRequest + ) : Call + + @POST("countries/weather/current") + fun getCurrentWeather( + @Body country: GetCountryInfoRequest + ) : Call + + @POST("countries/weather/weekly") + fun getWeeklyWeather( + @Body country: GetCountryInfoRequest + ) : Call +} \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/ScheduleService.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/ScheduleService.kt index 618b6799..e7767a1b 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/ScheduleService.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/api_interface/ScheduleService.kt @@ -3,7 +3,7 @@ package com.project.how.network.api_interface import com.project.how.data_class.dto.schedule.CreateScheduleListRequest import com.project.how.data_class.dto.schedule.CreateScheduleListResponse import com.project.how.data_class.dto.schedule.CreateScheduleResponse -import com.project.how.data_class.dto.country.GetCountryLocationRequest +import com.project.how.data_class.dto.country.GetCountryInfoRequest import com.project.how.data_class.dto.country.GetCountryLocationResponse import com.project.how.data_class.dto.schedule.GetFastestSchedulesResponse import com.project.how.data_class.dto.schedule.GetLatestSchedulesResponse @@ -62,7 +62,7 @@ interface ScheduleService { @POST("countries/locations") fun getCountryLocation( - @Body country : GetCountryLocationRequest + @Body country : GetCountryInfoRequest ) : Call @GET("schedules/dday") diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/BookingRetrofit.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/BookingRetrofit.kt index 52ddc741..4a247d7f 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/BookingRetrofit.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/BookingRetrofit.kt @@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit object BookingRetrofit { private const val BASE_URL = BuildConfig.API_SERVER - fun getApiService() : BookingService? = BookingRetrofit.getInstance() + fun getApiService() : BookingService? = getInstance() ?.create(BookingService::class.java) private fun getInstance() : Retrofit? { diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/CountryRetrofit.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/CountryRetrofit.kt new file mode 100644 index 00000000..d4cace89 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/network/client/CountryRetrofit.kt @@ -0,0 +1,41 @@ +package com.project.how.network.client + +import com.google.gson.GsonBuilder +import com.project.how.BuildConfig +import com.project.how.network.api_interface.CountryService +import com.project.how.network.converter_factory.NullOnEmptyConverterFactory +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.converter.scalars.ScalarsConverterFactory +import java.util.concurrent.TimeUnit + +object CountryRetrofit { + private const val BASE_URL = BuildConfig.API_SERVER + + fun getApiService() : CountryService? = getInstance() + ?.create(CountryService::class.java) + + private fun getInstance() : Retrofit? { + val gson = GsonBuilder().setLenient().create() + + val httpClient = OkHttpClient.Builder() + .connectTimeout(3, TimeUnit.MINUTES) + .readTimeout(2, TimeUnit.MINUTES) + .writeTimeout(1, TimeUnit.MINUTES) + + val loggingInterceptor = HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + httpClient.addInterceptor(loggingInterceptor) + + return Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(NullOnEmptyConverterFactory()) + .addConverterFactory(GsonConverterFactory.create(gson)) + .client(httpClient.build()) + .build() + } +} \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt index c218c754..f96245be 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/SplashActivity.kt @@ -4,6 +4,7 @@ import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log +import android.widget.Toast import androidx.activity.viewModels import androidx.databinding.DataBindingUtil import androidx.lifecycle.lifecycleScope @@ -47,6 +48,9 @@ class SplashActivity : AppCompatActivity() { if (check == MemberViewModel.SUCCESS){ moveMain() }else{ + if (check == MemberViewModel.ON_FAILURE){ + Toast.makeText(this@SplashActivity, getString(R.string.server_network_error), Toast.LENGTH_SHORT).show() + } moveLogin() } } diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ai/AddAICalendarActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ai/AddAICalendarActivity.kt index 7fec087f..04544453 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ai/AddAICalendarActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ai/AddAICalendarActivity.kt @@ -32,6 +32,7 @@ import com.project.how.view.dialog.bottom_sheet_dialog.DesBottomSheetDialog import com.project.how.view.dialog.bottom_sheet_dialog.PurposeBottomSheetDialog import com.project.how.view.dialog.bottom_sheet_dialog.ActivityBottomSheetDialog import com.project.how.view_model.AiScheduleViewModel +import com.project.how.view_model.CountryViewModel import com.project.how.view_model.ScheduleViewModel import kotlinx.coroutines.launch import java.text.SimpleDateFormat @@ -43,6 +44,7 @@ class AddAICalendarActivity : private lateinit var binding : ActivityAddAicalendarBinding private val viewModel : AiScheduleViewModel by viewModels() private val scheduleViewModel : ScheduleViewModel by viewModels() + private val countryViewModel : CountryViewModel by viewModels() private var destination : String? = null private var purpose : MutableList? = null private var activities : MutableList? = null @@ -228,14 +230,14 @@ class AddAICalendarActivity : override fun onDesListener(des: String) { lifecycleScope.launch { - scheduleViewModel.getCountryLocation(des).collect{ location -> + countryViewModel.getCountryLocation(des).collect{ location -> location?.let { destination = des binding.desOutput.text = des binding.desOutput.visibility = View.VISIBLE latLng = location } ?: run { - scheduleViewModel.getCountryLocation(des).collect { newLocation -> + countryViewModel.getCountryLocation(des).collect { newLocation -> newLocation?.let { destination = des binding.desOutput.text = des diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarEditActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarEditActivity.kt index 83496adb..253f379a 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarEditActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarEditActivity.kt @@ -46,6 +46,7 @@ import com.project.how.view.dp.DpPxChanger import com.project.how.view.map_helper.CameraOptionProducer import com.project.how.view.map_helper.MarkerProducer import com.project.how.view_model.CalendarViewModel +import com.project.how.view_model.CountryViewModel import com.project.how.view_model.MemberViewModel import com.project.how.view_model.ScheduleViewModel import kotlinx.coroutines.launch @@ -65,6 +66,7 @@ class CalendarEditActivity private lateinit var binding : ActivityCalendarEditBinding private val viewModel : ScheduleViewModel by viewModels() private val calendarViewModel : CalendarViewModel by viewModels() + private val countryViewModel : CountryViewModel by viewModels() private lateinit var data : Schedule private var type: Int = FAILURE private lateinit var adapter : DaysScheduleEditAdapter @@ -351,7 +353,6 @@ class CalendarEditActivity } private suspend fun saveNewSchedule(){ - viewModel.saveSchedule(this, MemberViewModel.tokensLiveData.value!!.accessToken, data).collect{check -> when(check){ ScheduleViewModel.NETWORK_FAILED ->{ @@ -449,13 +450,13 @@ class CalendarEditActivity override fun onDesListener(des: String) { lifecycleScope.launch { - viewModel.getCountryLocation(des).collect{ location -> + countryViewModel.getCountryLocation(des).collect{ location -> location?.let { data.country = des latitude = location.lat longitude = location.lng } ?: run { - viewModel.getCountryLocation(des).collect { newLocation -> + countryViewModel.getCountryLocation(des).collect { newLocation -> newLocation?.let { data.country = des latitude = newLocation.lat @@ -469,13 +470,23 @@ class CalendarEditActivity } } - override fun onSaveDate(d: DaysSchedule, date: String, position: Int) { + override fun onSaveDate( + d: DaysSchedule, + selectedDate: String, + changedDate: String, + position: Int + ) { val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) - val sd = format.parse(data.startDate) - val ssd = format.parse(date) + val sd = format.parse(selectedDate) + val ssd = format.parse(changedDate) val diffMillies = abs(sd.time - ssd.time) val diff = (diffMillies / (24 * 60 * 60 * 1000)).toInt() - data.dailySchedule[selectedDays+diff].add(d) + Log.d("getDateList", "onSaveDate\ndata.startDate : $sd\nchangeDate : ${ssd}\ndiff : $diff") + if (selectedDate>changedDate){ + data.dailySchedule[selectedDays-diff].add(d) + }else{ + data.dailySchedule[selectedDays+diff].add(d) + } adapter.remove(position, true) supportMapFragment.getMapAsync(this) diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarListActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarListActivity.kt index a1795c26..3116996e 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarListActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/calendar/CalendarListActivity.kt @@ -20,6 +20,7 @@ import com.project.how.interface_af.OnDesListener import com.project.how.interface_af.OnYesOrNoListener import com.project.how.view.dialog.YesOrNoDialog import com.project.how.view.dialog.bottom_sheet_dialog.DesBottomSheetDialog +import com.project.how.view_model.CountryViewModel import com.project.how.view_model.MemberViewModel import com.project.how.view_model.ScheduleViewModel import kotlinx.coroutines.launch @@ -32,6 +33,7 @@ class CalendarListActivity private lateinit var binding : ActivityCalendarListBinding private lateinit var adapter : CalendarListAdapter private val viewModel : ScheduleViewModel by viewModels() + private val countryViewModel : CountryViewModel by viewModels() private var destination : String? = null private var departureDate : String? = null private var entranceDate : String? = null @@ -110,9 +112,9 @@ class CalendarListActivity override fun onDeleteButtonClickListener(data : GetScheduleListResponseElement, position : Int) { val yesOrNoDialog = YesOrNoDialog(data.scheduleName, YesOrNoDialog.SCHEDULE_DELETE, position, this) + Log.d("onDelete", "position : ${position}") yesOrNoDialog.show(supportFragmentManager, "YesOrNoDialog") } - override fun onItemClickListener(id: Long, latitude : Double, longitude : Double) { Log.d("onCreate", "onItemClickerListener\nid : ${id}\nlatitude : ${latitude}\tlongitude : ${longitude}") val intent = Intent(this, CalendarActivity::class.java) @@ -134,6 +136,7 @@ class CalendarListActivity override fun onScheduleDeleteListener(position: Int) { lifecycleScope.launch { val data = adapter.getData(position) + Log.d("onDelete", "onScheduleDeleteListener\nposition: $position\tid : ${data.id}\ttitle : ${data.scheduleName}") viewModel.deleteSchedule(this@CalendarListActivity, MemberViewModel.tokensLiveData.value!!.accessToken, data.id).collect{ when(it){ ScheduleViewModel.SUCCESS -> { adapter.remove(position) } @@ -155,13 +158,13 @@ class CalendarListActivity override fun onDesListener(des: String) { lifecycleScope.launch { - viewModel.getCountryLocation(des).collect{ location -> + countryViewModel.getCountryLocation(des).collect{ location -> location?.let { destination = des latLng = location showCalendar() } ?: run { - viewModel.getCountryLocation(des).collect { newLocation -> + countryViewModel.getCountryLocation(des).collect { newLocation -> newLocation?.let { destination = des latLng = newLocation diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/mypage/WeatherActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/mypage/WeatherActivity.kt index 4a9e8609..4caa2f33 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/mypage/WeatherActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/mypage/WeatherActivity.kt @@ -1,21 +1,97 @@ package com.project.how.view.activity.mypage import android.os.Bundle +import android.widget.Toast import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.databinding.DataBindingUtil +import androidx.lifecycle.lifecycleScope +import com.bumptech.glide.Glide +import com.project.how.BuildConfig import com.project.how.R +import com.project.how.adapter.recyclerview.weather.WeekWeatherAdapter import com.project.how.databinding.ActivityWeatherBinding +import com.project.how.interface_af.interface_ff.OnAirportListener +import com.project.how.view.dialog.bottom_sheet_dialog.AirportBottomSheetDialog +import com.project.how.view_model.CalendarViewModel +import com.project.how.view_model.CountryViewModel +import kotlinx.coroutines.launch +import kotlin.math.roundToInt -class WeatherActivity : AppCompatActivity() { +class WeatherActivity : AppCompatActivity(), OnAirportListener { private lateinit var binding : ActivityWeatherBinding + private val viewModel : CountryViewModel by viewModels() + private val calendarViewModel : CalendarViewModel by viewModels() + private lateinit var adapter : WeekWeatherAdapter + private lateinit var country : String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_weather) binding.weather = this binding.lifecycleOwner = this + adapter = WeekWeatherAdapter(listOf()) + binding.week.adapter = adapter + + country = getString(R.string.inchon) + update(country) + + viewModel.currentWeatherLiveData.observe(this){ + val temp = it.temp.toDouble().roundToInt().toString() + val minTemp = it.tempMin.toDouble().roundToInt().toString() + val maxTemp = it.tempMax.toDouble().roundToInt().toString() + binding.main.text = viewModel.changeMainToKorean(it.main) + binding.temp.text = getString(R.string.temp, temp) + binding.country.text = country + binding.dateTime.text = calendarViewModel.getWeatherDateTime(it.localTime) + binding.minAndMaxTemps.text = getString(R.string.min_and_max_temps, minTemp, maxTemp) + binding.description.text = it.description + Glide.with(binding.root) + .load(it.iconUrl) + .error(BuildConfig.ERROR_IMAGE_URl) + .into(binding.image) + } + + viewModel.weeklyWeatherLiveData.observe(this){ + adapter.update(it) + } + + + } + + fun update(country : String){ + lifecycleScope.launch { + viewModel.getCurrentWeather(country).collect{check-> + if (!check){ + Toast.makeText(this@WeatherActivity, getString(R.string.server_network_error), Toast.LENGTH_SHORT).show() + binding.main.text = "" + binding.temp.text = getString(R.string.error) + binding.country.text = getString(R.string.error) + binding.dateTime.text = getString(R.string.error) + binding.description.text = "" + binding.minAndMaxTemps.text = "" + } + } + } + lifecycleScope.launch { + viewModel.getWeeklyWeathers(country).collect{check-> + if (!check){ + Toast.makeText(this@WeatherActivity, getString(R.string.server_network_error), Toast.LENGTH_SHORT).show() + } + } + } + } + + fun showGlobal(){ + val global = AirportBottomSheetDialog(0, this) + global.show(supportFragmentManager, "AirportBottomSheetDialog") + } + + override fun onAirportListener(type: Int, airport: String) { + country = airport + update(country) } } \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/OneWayAirplaneListActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/OneWayAirplaneListActivity.kt index b740e2d0..5cec28ff 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/OneWayAirplaneListActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/OneWayAirplaneListActivity.kt @@ -51,17 +51,19 @@ class OneWayAirplaneListActivity : AppCompatActivity(), OneWayAirplaneListAdapte binding.airplaneList.adapter = adapter bookingViewModel.skyscannerUrlLiveData.observe(this){url-> - val web = WebViewBottomSheetDialog(url) - web.show(supportFragmentManager, "WebViewBottomSheetDialog") - val recent = RecentAirplane( - name = getString(R.string.recent_one_way_name, input.departure, input.destination), - image = null, - des = input.departure, - time1 = getString(R.string.date_text, clicked!!.abroadDepartureTime, clicked!!.abroadArrivalTime), - time2 = null, - skyscannerUrl = url - ) - bookingViewModel.addRecentAirplane(recent) + if (clicked != null){ + val web = WebViewBottomSheetDialog(url) + web.show(supportFragmentManager, "WebViewBottomSheetDialog") + val recent = RecentAirplane( + name = getString(R.string.recent_one_way_name, input.departure, input.destination), + image = null, + des = input.departure, + time1 = getString(R.string.date_text, clicked!!.abroadDepartureTime, clicked!!.abroadArrivalTime), + time2 = null, + skyscannerUrl = url + ) + bookingViewModel.addRecentAirplane(recent) + } } bookingViewModel.likeFlightListLiveData.observe(this){ diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/RoundTripAirplaneListActivity.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/RoundTripAirplaneListActivity.kt index 0c8f5c88..937efa26 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/RoundTripAirplaneListActivity.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/activity/ticket/RoundTripAirplaneListActivity.kt @@ -53,17 +53,19 @@ class RoundTripAirplaneListActivity : AppCompatActivity(), RoundTripAirplaneList getString(R.string.get_flight_offers_request), GetFlightOffersRequest::class.java) bookingViewModel.skyscannerUrlLiveData.observe(this){url-> - val web = WebViewBottomSheetDialog(url) - web.show(supportFragmentManager, "WebViewBottomSheetDialog") - val recent = RecentAirplane( - name = getString(R.string.recent_round_trip_name, input.departure, input.destination), - image = null, - des = input.departure, - time1 = getString(R.string.date_text, clicked!!.abroadDepartureTime, clicked!!.abroadArrivalTime), - time2 = getString(R.string.date_text, clicked!!.homeDepartureTime, clicked!!.homeArrivalTime), - skyscannerUrl = url - ) - bookingViewModel.addRecentAirplane(recent) + if (clicked != null){ + val web = WebViewBottomSheetDialog(url) + web.show(supportFragmentManager, "WebViewBottomSheetDialog") + val recent = RecentAirplane( + name = getString(R.string.recent_round_trip_name, input.departure, input.destination), + image = null, + des = input.departure, + time1 = getString(R.string.date_text, clicked!!.abroadDepartureTime, clicked!!.abroadArrivalTime), + time2 = getString(R.string.date_text, clicked!!.homeDepartureTime, clicked!!.homeArrivalTime), + skyscannerUrl = url + ) + bookingViewModel.addRecentAirplane(recent) + } } bookingViewModel.likeFlightListLiveData.observe(this){ diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/DatePickerDialog.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/DatePickerDialog.kt index 820e387e..fc6ce9f9 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/DatePickerDialog.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/DatePickerDialog.kt @@ -3,6 +3,7 @@ package com.project.how.view.dialog import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -54,7 +55,8 @@ class DatePickerDialog(private val data : DaysSchedule, private val dates : List fun save(){ val date = getCheckedRadioButtonDate() - onDateTimeListener.onSaveDate(data, date, position) + Log.d("getDateList", "name : ${data.todo}\nselecetedDate : ${dates[selectedDays]}\nchangedDate : $date\nposition : $position") + onDateTimeListener.onSaveDate(data, dates[selectedDays], date, position) dismiss() } diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/bottom_sheet_dialog/AirportBottomSheetDialog.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/bottom_sheet_dialog/AirportBottomSheetDialog.kt index 324dd38b..7b19cd94 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/bottom_sheet_dialog/AirportBottomSheetDialog.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/dialog/bottom_sheet_dialog/AirportBottomSheetDialog.kt @@ -36,8 +36,8 @@ class AirportBottomSheetDialog(private val type: Int, private val onAirportListe super.onCreate(savedInstanceState) lifecycleScope.launch { koreaAirports = mutableListOf( - "인천", - "김포" + getString(R.string.inchon), + getString(R.string.gimpo) ) japanAirports = mutableListOf( diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/main/CalendarFragment.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/main/CalendarFragment.kt index 39eafb5f..2817ac4c 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/main/CalendarFragment.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view/fragment/main/CalendarFragment.kt @@ -33,6 +33,7 @@ import com.project.how.view.activity.calendar.CalendarActivity import com.project.how.view.activity.calendar.CalendarEditActivity import com.project.how.view.activity.calendar.CalendarListActivity import com.project.how.view.dialog.bottom_sheet_dialog.DesBottomSheetDialog +import com.project.how.view_model.CountryViewModel import com.project.how.view_model.MemberViewModel import com.project.how.view_model.ScheduleViewModel import kotlinx.coroutines.Job @@ -46,6 +47,7 @@ class CalendarFragment : Fragment(), OnDesListener, RecentAddedCalendarsAdapter. private val binding : FragmentCalendarBinding get() = _binding!! private val scheduleViewModel : ScheduleViewModel by viewModels() + private val countryViewModel : CountryViewModel by viewModels() private var nearSchedule : GetFastestSchedulesResponse? = null private val event = mutableListOf() private lateinit var recentAddedCalendar : GetLatestSchedulesResponse @@ -216,13 +218,13 @@ class CalendarFragment : Fragment(), OnDesListener, RecentAddedCalendarsAdapter. override fun onDesListener(des: String) { lifecycleScope.launch { - scheduleViewModel.getCountryLocation(des).collect{ location -> + countryViewModel.getCountryLocation(des).collect{ location -> location?.let { destination = des latLng = location showCalendar() } ?: run { - scheduleViewModel.getCountryLocation(des).collect { newLocation -> + countryViewModel.getCountryLocation(des).collect { newLocation -> newLocation?.let { destination = des latLng = newLocation diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt index 3348115a..2ab7ba8c 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CalendarViewModel.kt @@ -1,11 +1,13 @@ package com.project.how.view_model +import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import com.project.how.model.CalendarRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import java.time.LocalDate +import java.time.LocalDateTime import java.time.format.DateTimeFormatter class CalendarViewModel : ViewModel() { @@ -27,7 +29,16 @@ class CalendarViewModel : ViewModel() { for(i in 1 ..lastIndex){ sd = sd.plusDays(1) result.add(sd.format(formatter)) + Log.d("getDateList", "${sd.format(formatter)}") } emit(result) } + + fun getWeatherDateTime(dateTime : String) : String { + val inputFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") + val outputFormatter = DateTimeFormatter.ofPattern("MM월 dd일 HH:mm") + + val localDateTime = LocalDateTime.parse(dateTime, inputFormatter) + return localDateTime.format(outputFormatter) + } } \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CountryViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CountryViewModel.kt new file mode 100644 index 00000000..70e8d4c8 --- /dev/null +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/CountryViewModel.kt @@ -0,0 +1,164 @@ +package com.project.how.view_model + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import com.project.how.data_class.dto.country.GetCountryInfoRequest +import com.project.how.data_class.dto.country.GetCountryLocationResponse +import com.project.how.data_class.dto.country.weather.GetCurrentWeatherResponse +import com.project.how.data_class.dto.country.weather.GetWeeklyWeathersResponse +import com.project.how.model.CountryRepository +import com.project.how.network.client.CountryRetrofit +import com.project.how.network.client.ScheduleRetrofit +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.flow +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class CountryViewModel : ViewModel() { + private var countryRepository : CountryRepository = CountryRepository() + private val _currentWeatherLiveData = countryRepository.currentWeatherLiveData + private val _weeklyWeathersLiveData = countryRepository.weeklyWeathersLiveData + val currentWeatherLiveData : LiveData + get() = _currentWeatherLiveData + val weeklyWeatherLiveData : LiveData + get() = _weeklyWeathersLiveData + + fun getCountryLocation(country : String) : Flow = callbackFlow { + CountryRetrofit.getApiService()?.let { apiService -> + apiService.getCountryLocation(GetCountryInfoRequest(country)) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful){ + val result = response.body() + if (result != null){ + Log.d("getCountryLocation", "country : $country\nlat : ${result.lat}\tlng : ${result.lng}") + trySend(result) + close() + }else{ + Log.d("getCountryLocation", "response code : ${response.code()}") + trySend(null) + } + }else{ + Log.d("getCountryLocation", "response code : ${response.code()}") + trySend(null) + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.d("getCountryLocation", "${t.message}") + trySend(null) + } + + }) + } ?: close() + + awaitClose() + } + + fun getCurrentWeather(country: String) : Flow = callbackFlow { + CountryRetrofit.getApiService()?.let { apiService-> + apiService.getCurrentWeather(GetCountryInfoRequest(country)) + .enqueue(object : Callback{ + override fun onResponse( + p0: Call, + p1: Response + ) { + if (p1.isSuccessful){ + val result = p1.body() + if (result != null){ + Log.d("getCurrentWeather", "country : $country\ntemp : ${result.temp}") + countryRepository.getCurrentWeather(result) + trySend(true) + }else{ + Log.d("getCurrentWeather", "response.body is null") + trySend(false) + } + + }else{ + Log.d("getCurrentWeather", "response is failed.") + trySend(false) + } + } + + override fun onFailure(p0: Call, p1: Throwable) { + Log.d("getCurrentWeather", "${p1.message}") + trySend(false) + } + + }) + } ?: close() + + awaitClose() + } + + fun getWeeklyWeathers(country: String) : Flow = callbackFlow { + CountryRetrofit.getApiService()?.let { apiService-> + apiService.getWeeklyWeather(GetCountryInfoRequest(country)) + .enqueue(object : Callback{ + override fun onResponse( + p0: Call, + p1: Response + ) { + if (p1.isSuccessful){ + val result = p1.body() + if (result != null){ + Log.d("getWeeklyWeathers", "length : ${result.size}") + countryRepository.getWeeklyWeathers(result) + trySend(true) + }else{ + Log.d("getWeeklyWeathers", "response.body is null") + trySend(false) + } + }else{ + Log.d("getWeeklyWeathers", "response is failed.") + trySend(false) + } + } + + override fun onFailure(p0: Call, p1: Throwable) { + Log.d("getWeeklyWeather", "${p1.message}") + trySend(false) + } + + }) + + } ?: close() + + awaitClose() + } + + fun changeMainToKorean(main : String) : String{ + var m = "" + + when(main){ + "Clear" -> m = "맑음" + "Clouds" -> m = "흐림" + "Thunderstorm" -> m = "번개" + "Drizzle" -> m = "이슬비" + "Rain" -> m = "비" + "Snow" -> m = "눈" + "Mist" -> m = "안개" + "Smoke" -> m = "연기" + "Haze" -> m = "옅은 안개" + "Fog" -> m = "짙은 안개" + "Dust" -> m = "먼지" + "Ash" -> m = "화산재" + "Squalls" -> m = "돌풍" + "Tornado" -> m = "폭풍" + else -> { + m = "알 수 없음" + Log.d("changeMainToKorea(Weather)", "main : ${main}") + } + } + + return m + + } +} \ No newline at end of file diff --git a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/ScheduleViewModel.kt b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/ScheduleViewModel.kt index 13dd2d37..bfbd7135 100644 --- a/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/ScheduleViewModel.kt +++ b/android/HowAboutTrip/app/src/main/java/com/project/how/view_model/ScheduleViewModel.kt @@ -11,7 +11,7 @@ import com.project.how.data_class.recyclerview.AiSchedule import com.project.how.data_class.recyclerview.DaysSchedule import com.project.how.data_class.recyclerview.Schedule import com.project.how.data_class.dto.schedule.DailySchedule -import com.project.how.data_class.dto.country.GetCountryLocationRequest +import com.project.how.data_class.dto.country.GetCountryInfoRequest import com.project.how.data_class.dto.country.GetCountryLocationResponse import com.project.how.data_class.dto.schedule.GetFastestSchedulesResponse import com.project.how.data_class.dto.schedule.GetLatestSchedulesResponse @@ -367,41 +367,6 @@ class ScheduleViewModel : ViewModel() { awaitClose() } - fun getCountryLocation(country : String) : Flow = callbackFlow { - ScheduleRetrofit.getApiService()?.let {apiService -> - apiService.getCountryLocation(GetCountryLocationRequest(country)) - .enqueue(object : Callback{ - override fun onResponse( - call: Call, - response: Response - ) { - if (response.isSuccessful){ - val result = response.body() - if (result != null){ - Log.d("getCountryLocation", "country : $country\nlat : ${result.lat}\tlng : ${result.lng}") - trySend(result) - close() - }else{ - Log.d("getCountryLocation", "response code : ${response.code()}") - trySend(null) - } - }else{ - Log.d("getCountryLocation", "response code : ${response.code()}") - trySend(null) - } - } - - override fun onFailure(call: Call, t: Throwable) { - Log.d("getCountryLocation", "${t.message}") - trySend(null) - } - - }) - } ?: close() - - awaitClose() - } - companion object{ const val NULL_LOCATIONS = -1 const val NETWORK_FAILED = -2 diff --git a/android/HowAboutTrip/app/src/main/res/layout/activity_weather.xml b/android/HowAboutTrip/app/src/main/res/layout/activity_weather.xml index 31433d2d..92a10694 100644 --- a/android/HowAboutTrip/app/src/main/res/layout/activity_weather.xml +++ b/android/HowAboutTrip/app/src/main/res/layout/activity_weather.xml @@ -44,6 +44,7 @@ android:background="@android:color/transparent" android:scaleType="fitCenter" android:layout_marginEnd="8dp" + android:onClick="@{()-> weather.showGlobal()}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/alarm" app:layout_constraintTop_toTopOf="parent" /> @@ -68,12 +69,87 @@ android:layout_height="wrap_content" android:text="@string/england" android:textFontWeight="1000" - android:textSize="24sp" + android:textSize="22sp" android:layout_marginTop="40dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/toolbar" /> + + + + + + + + + + + + + + 여행 기록 여행 지출 총 예산 비용 : %1$s 원 + %1$s℃ / %2$s℃ + %1$s℃ + 현지 시간 + 인천 + 김포 \ No newline at end of file