diff --git a/AOS/.idea/gradle.xml b/AOS/.idea/gradle.xml index ae388c2a..cb865f69 100644 --- a/AOS/.idea/gradle.xml +++ b/AOS/.idea/gradle.xml @@ -4,8 +4,6 @@ diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardClickListener.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardClickListener.kt deleted file mode 100644 index 47b36761..00000000 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardClickListener.kt +++ /dev/null @@ -1,9 +0,0 @@ -package boostcamp.and07.mindsync.ui.boardlist - -import boostcamp.and07.mindsync.data.model.Board - -interface BoardClickListener { - fun onClick(board: Board) - - fun onCheckBoxClick(board: Board) -} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListAdapter.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListAdapter.kt deleted file mode 100644 index c76c9805..00000000 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListAdapter.kt +++ /dev/null @@ -1,71 +0,0 @@ -package boostcamp.and07.mindsync.ui.boardlist - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import boostcamp.and07.mindsync.data.model.Board -import boostcamp.and07.mindsync.databinding.ItemBoardBinding - -class BoardListAdapter : ListAdapter(DIFF_CALLBACK) { - private var boardClickListener: BoardClickListener? = null - - fun setBoardClickListener(listener: BoardClickListener) { - this.boardClickListener = listener - } - - class BoardListViewHolder( - private val binding: ItemBoardBinding, - private val boardClickListener: BoardClickListener?, - ) : - RecyclerView.ViewHolder(binding.root) { - fun bind(item: Board) { - with(binding) { - board = item - cbBoard.isChecked = item.isChecked - imgbtnBoardItem.setOnClickListener { - boardClickListener?.onClick(item) - } - cbBoard.setOnClickListener { - item.isChecked = !item.isChecked - boardClickListener?.onCheckBoxClick(item) - } - } - } - } - - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int, - ): BoardListViewHolder { - val binding = ItemBoardBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return BoardListViewHolder(binding, boardClickListener) - } - - override fun onBindViewHolder( - holder: BoardListViewHolder, - position: Int, - ) { - holder.bind(getItem(position)) - } - - companion object { - val DIFF_CALLBACK = - object : DiffUtil.ItemCallback() { - override fun areItemsTheSame( - oldItem: Board, - newItem: Board, - ): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame( - oldItem: Board, - newItem: Board, - ): Boolean { - return oldItem == newItem - } - } - } -} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListBindingAdpater.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListBindingAdpater.kt deleted file mode 100644 index 881433aa..00000000 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/boardlist/BoardListBindingAdpater.kt +++ /dev/null @@ -1,48 +0,0 @@ -package boostcamp.and07.mindsync.ui.boardlist - -import androidx.databinding.BindingAdapter -import androidx.recyclerview.widget.RecyclerView -import boostcamp.and07.mindsync.R -import boostcamp.and07.mindsync.data.model.Board -import com.google.android.flexbox.FlexboxLayoutManager -import com.google.android.flexbox.JustifyContent -import com.google.android.material.floatingactionbutton.FloatingActionButton - -@BindingAdapter("app:boards") -fun RecyclerView.bindBoards(boards: List) { - if (this.adapter != null) { - (this.adapter as BoardListAdapter).submitList(boards.toMutableList()) - } -} - -@BindingAdapter("app:flexBoxLayoutManager") -fun RecyclerView.bindLayoutManager(direction: Int) { - this.layoutManager = - FlexboxLayoutManager(context).apply { - flexDirection = direction - justifyContent = JustifyContent.CENTER - } -} - -@BindingAdapter("app:floatingButtonImage") -fun FloatingActionButton.bindImage(selectBoards: List) { - if (selectBoards.isEmpty()) { - this.setImageDrawable(context.getDrawable(R.drawable.ic_add_board)) - } else { - this.setImageDrawable(context.getDrawable(R.drawable.ic_delete_board)) - } -} - -@BindingAdapter("app:floatingButtonImage", "app:onClickListener") -fun FloatingActionButton.bindImageButton( - selectBoards: List, - clickListener: () -> Unit, -) { - if (selectBoards.isEmpty()) { - this.setImageDrawable(context.getDrawable(R.drawable.ic_add_board)) - this.setOnClickListener { clickListener() } - } else { - this.setImageDrawable(context.getDrawable(R.drawable.ic_delete_board)) - this.setOnClickListener { clickListener() } - } -} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardDialog.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardDialog.kt deleted file mode 100644 index 74dd95a4..00000000 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardDialog.kt +++ /dev/null @@ -1,218 +0,0 @@ -package boostcamp.and07.mindsync.ui.dialog - -import android.Manifest -import android.app.ActionBar.LayoutParams -import android.app.Activity.RESULT_OK -import android.app.Dialog -import android.content.DialogInterface -import android.content.Intent -import android.content.pm.PackageManager -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.net.Uri -import android.os.Build -import android.os.Bundle -import android.provider.MediaStore -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.view.WindowManager -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat.checkSelfPermission -import androidx.fragment.app.DialogFragment -import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope -import boostcamp.and07.mindsync.R -import boostcamp.and07.mindsync.databinding.DialogCreateBoardBinding -import boostcamp.and07.mindsync.ui.util.setClickEvent -import boostcamp.and07.mindsync.ui.util.toAbsolutePath -import dagger.hilt.android.AndroidEntryPoint -import okhttp3.MultipartBody -import java.io.File - -@AndroidEntryPoint -class CreateBoardDialog : DialogFragment() { - private var _binding: DialogCreateBoardBinding? = null - private val binding get() = _binding!! - - private val createBoardViewModel: CreateBoardViewModel by viewModels() - - private var completeListener: ((MultipartBody.Part?, String) -> (Unit))? = null - - private val pickMedia = - registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { url -> - url?.let { - val file = File(url.toAbsolutePath(requireContext())) - createBoardViewModel.setBoardImage(url.toString()) - createBoardViewModel.setImageFile(file) - } - } - private val galleryPermissionLauncher = - registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> - if (isGranted) { - launchImagePicker() - } - } - - private val imageResult = - registerForActivityResult( - ActivityResultContracts.StartActivityForResult(), - ) { result -> - Log.d("CreateBoardDialog", "result: ${result.resultCode}") - if (result.resultCode == RESULT_OK) { - result.data?.data?.let { uri -> - createImage(uri) - } - } - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - dialog.window?.attributes?.windowAnimations = R.style.AnimationDialogStyle - isCancelable = true - return dialog - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - _binding = DialogCreateBoardBinding.inflate(inflater, container, false) - setBinding() - setClickEventThrottle() - return binding.root - } - - private fun setBinding() { - binding.view = this - binding.vm = createBoardViewModel - binding.lifecycleOwner = this - } - - override fun onStart() { - super.onStart() - resizeDialog() - } - - private fun resizeDialog() { - val params: ViewGroup.LayoutParams? = dialog?.window?.attributes - - val displayMetrics = requireActivity().resources.displayMetrics - val deviceWidth = displayMetrics.widthPixels - val deviceHeight = displayMetrics.heightPixels - - params?.width = (deviceWidth * 0.8).toInt() - params?.height = LayoutParams.WRAP_CONTENT - dialog?.window?.attributes = params as WindowManager.LayoutParams - } - - override fun onDismiss(dialog: DialogInterface) { - _binding = null - super.onDismiss(dialog) - } - - fun onClickCompleteButton(imageName: String) { - val result = createBoardViewModel.changeImageToFile(imageName) - completeListener?.invoke(result.first, result.second) - dismiss() - } - - private fun setClickEventThrottle() { - binding.imgbtnUpdateSpaceThumbnail.setClickEvent(lifecycleScope) { - checkPermissionsAndLaunchImagePicker() - } - } - - private fun createImage(uri: Uri?) { - uri?.let { uri -> - createBoardViewModel.setBoardImage(uri.toString()) - } - } - - private fun checkPermissionsAndLaunchImagePicker() { - when { - checkSelfPermission( - requireContext(), - getPermissionReadMediaImagesOrReadExternalStorage(), - ) == PackageManager.PERMISSION_GRANTED -> { - launchImagePicker() - } - - shouldShowRequestPermissionRationale( - getPermissionReadMediaImagesOrReadExternalStorage(), - ) -> { - requestGalleryPermission() - } - - else -> { - requestGalleryPermission() - } - } - } - - private fun launchImagePicker() { - pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) - } - - private fun getPermissionReadMediaImagesOrReadExternalStorage() = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - Manifest.permission.READ_MEDIA_IMAGES - } else { - Manifest.permission.READ_EXTERNAL_STORAGE - } - - private fun requestGalleryPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - galleryPermissionLauncher.launch(Manifest.permission.READ_MEDIA_IMAGES) - } else { - checkPermissionAndLaunchImageSelector() - } - } - - private fun checkPermissionAndLaunchImageSelector() { - val readPermission = - checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) - - if (readPermission == PackageManager.PERMISSION_GRANTED) { - launchImageSelector() - } else { - requestExternalStoragePermission() - } - } - - private fun requestExternalStoragePermission() { - ActivityCompat.requestPermissions( - requireActivity(), - arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), - REQUEST_CODE_PERMISSIONS, - ) - } - - private fun launchImageSelector() { - val intent = - Intent(Intent.ACTION_PICK).apply { - setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*") - } - imageResult.launch(intent) - } - - override fun onRequestPermissionsResult( - requestCode: Int, - permissions: Array, - grantResults: IntArray, - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - if (requestCode == REQUEST_CODE_PERMISSIONS && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - launchImagePicker() - } - } - - companion object { - private const val REQUEST_CODE_PERMISSIONS = 1 - } -} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardViewModel.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardViewModel.kt deleted file mode 100644 index c36b1930..00000000 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/CreateBoardViewModel.kt +++ /dev/null @@ -1,65 +0,0 @@ -package boostcamp.and07.mindsync.ui.dialog - -import boostcamp.and07.mindsync.data.repository.login.LogoutEventRepository -import boostcamp.and07.mindsync.ui.base.BaseActivityViewModel -import boostcamp.and07.mindsync.ui.util.fileToMultiPart -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.update -import okhttp3.MultipartBody -import java.io.File -import javax.inject.Inject - -@HiltViewModel -class CreateBoardViewModel - @Inject - constructor( - logoutEventRepository: LogoutEventRepository, - ) : BaseActivityViewModel(logoutEventRepository) { - private val _uiState = MutableStateFlow(CreateBoardUiState()) - val uiState: StateFlow = _uiState - - private var imageFile: File? = null - - fun onBoardNameChanged( - inputSpaceName: CharSequence, - start: Int, - before: Int, - count: Int, - ) { - _uiState.update { uiState -> - uiState.copy(boardName = inputSpaceName.toString()) - } - } - - fun setBoardImage(boardImage: String) { - _uiState.update { uiState -> - uiState.copy(boardImage = boardImage) - } - } - - fun changeImageToFile(imageName: String): Pair { - val icon = - imageFile?.let { imageFile -> - fileToMultiPart(imageFile, imageName) - } - val name = _uiState.value.boardName - _uiState.update { uiState -> - uiState.copy(boardName = name) - } - return Pair(icon, name) - } - - fun setImageFile(file: File) { - _uiState.update { uiState -> - uiState.copy(boardThumbnailFile = file) - } - } - } - -data class CreateBoardUiState( - val boardName: String = "", - val boardImage: String = "", - val boardThumbnailFile: File? = null, -) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/BindingAdapter.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/BindingAdapter.kt index e1eca002..998360c8 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/BindingAdapter.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/BindingAdapter.kt @@ -5,9 +5,12 @@ import android.widget.Button import android.widget.ImageView import android.widget.TextView import androidx.databinding.BindingAdapter +import androidx.recyclerview.widget.RecyclerView import boostcamp.and07.mindsync.R import coil.load import coil.transform.CircleCropTransformation +import com.google.android.flexbox.FlexboxLayoutManager +import com.google.android.flexbox.JustifyContent import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -47,3 +50,12 @@ fun Button.bindEnabled(content: String) { else -> false } } + +@BindingAdapter("app:flexBoxLayoutManager") +fun RecyclerView.bindLayoutManager(direction: Int) { + this.layoutManager = + FlexboxLayoutManager(context).apply { + flexDirection = direction + justifyContent = JustifyContent.CENTER + } +} diff --git a/AOS/app/src/main/res/layout/dialog_create_board.xml b/AOS/app/src/main/res/layout/dialog_create_board.xml deleted file mode 100644 index c2d4d065..00000000 --- a/AOS/app/src/main/res/layout/dialog_create_board.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/AOS/app/src/main/res/layout/fragment_board_list.xml b/AOS/app/src/main/res/layout/fragment_board_list.xml deleted file mode 100644 index 589904dc..00000000 --- a/AOS/app/src/main/res/layout/fragment_board_list.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AOS/app/src/main/res/layout/item_board.xml b/AOS/app/src/main/res/layout/item_board.xml deleted file mode 100644 index 462529aa..00000000 --- a/AOS/app/src/main/res/layout/item_board.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file