From a3ef5ac2a7644ae6a91189d14e0a251ae46eb41c Mon Sep 17 00:00:00 2001 From: kkjsw17 Date: Sun, 20 Jun 2021 20:33:55 +0900 Subject: [PATCH 1/2] Modify Entire UI --- app/src/main/res/layout/item_article.xml | 14 ++++++++------ app/src/main/res/layout/item_card.xml | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/layout/item_article.xml b/app/src/main/res/layout/item_article.xml index 669e747..05bb63f 100644 --- a/app/src/main/res/layout/item_article.xml +++ b/app/src/main/res/layout/item_article.xml @@ -72,7 +72,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:padding="6dp" - android:scaleType="center" + android:scaleType="centerCrop" android:src="@drawable/profile_image" app:srcCompat="@drawable/ic_launcher_foreground" /> @@ -94,10 +94,11 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" - android:gravity="center" + android:gravity="center|right" android:layout_marginTop="4dp" android:text="1" - android:textSize="40sp" /> + android:textSize="32sp" + tools:ignore="RtlHardcoded" /> + android:textSize="32sp" /> + android:textSize="32sp" + tools:ignore="RtlHardcoded" /> diff --git a/app/src/main/res/layout/item_card.xml b/app/src/main/res/layout/item_card.xml index 757c15b..a496db6 100644 --- a/app/src/main/res/layout/item_card.xml +++ b/app/src/main/res/layout/item_card.xml @@ -18,8 +18,7 @@ + android:layout_weight="3"> @@ -53,7 +52,7 @@ android:layout_weight="1" android:gravity="center" android:text="1" - android:textSize="32sp" /> + android:textSize="28sp" /> + android:textSize="28sp" /> + android:textSize="28sp" /> @@ -116,7 +115,9 @@ android:paddingTop="5dp" android:hint="@string/article_title" android:textColor="@color/black" - android:textSize="20sp" /> + android:textSize="20sp" + android:ellipsize="end" + android:maxLines="1" /> @@ -156,7 +157,7 @@ android:id="@+id/contentTextView" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="4" + android:layout_weight="3" android:padding="20dp" android:hint="@string/content" /> @@ -164,7 +165,7 @@ android:id="@+id/tagView" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1.5" + android:layout_weight="2.5" android:orientation="vertical" android:padding="20dp" /> From e28ee954eaff7431207040e6365198b96c51fe54 Mon Sep 17 00:00:00 2001 From: easyhooon <51016231+easyhooon@users.noreply.github.com> Date: Sun, 20 Jun 2021 20:55:02 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konkuk/koogle/Activity/ArticleActivity.kt | 39 ++++- .../main/java/kr/ac/konkuk/koogle/DBKeys.kt | 1 + .../ac/konkuk/koogle/Fragment/CardFragment.kt | 137 +++++++++++++++--- .../koogle/Fragment/CommunityFragment.kt | 80 +++++++--- .../kr/ac/konkuk/koogle/Model/UserModel.kt | 5 +- 5 files changed, 221 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/kr/ac/konkuk/koogle/Activity/ArticleActivity.kt b/app/src/main/java/kr/ac/konkuk/koogle/Activity/ArticleActivity.kt index b6bbd4f..f3f703e 100644 --- a/app/src/main/java/kr/ac/konkuk/koogle/Activity/ArticleActivity.kt +++ b/app/src/main/java/kr/ac/konkuk/koogle/Activity/ArticleActivity.kt @@ -44,6 +44,7 @@ import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_IMAGE_PATH import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_TITLE import kr.ac.konkuk.koogle.DBKeys.Companion.CURRENT_NUMBER import kr.ac.konkuk.koogle.DBKeys.Companion.DB_ARTICLES +import kr.ac.konkuk.koogle.DBKeys.Companion.DB_BLOCK_USERS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_GROUPS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_MAIN_TAGS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_USERS @@ -69,6 +70,7 @@ class ArticleActivity : AppCompatActivity() { val scope = CoroutineScope(Dispatchers.Main) private lateinit var writerId:String + private lateinit var writerName:String private lateinit var articleId:String private lateinit var articleTitle:String @@ -116,6 +118,10 @@ class ArticleActivity : AppCompatActivity() { Firebase.database.reference.child(DB_GROUPS).child(articleId).child(DB_USERS).child(currentUserId) } + private val currentUserBlockRef: DatabaseReference by lazy { + currentUserRef.child(DB_BLOCK_USERS) + } + private val storage: FirebaseStorage by lazy { Firebase.storage } @@ -205,7 +211,26 @@ class ArticleActivity : AppCompatActivity() { ad.show() } R.id.userBlock -> { - Toast.makeText(this@ArticleActivity, "해당 유저를 차단하였습니다", Toast.LENGTH_SHORT).show() + //dialog 한번 뿌리고 진짜 삭제 + val ad = AlertDialog.Builder(this@ArticleActivity) + ad.setMessage("해당 유저를 차단하시겠습니까? \n차단하시면 해당 유저의 글을 볼 수 없습니다.") + ad.setPositiveButton( + "취소" + ) { dialog, _ -> + dialog.dismiss() + } + ad.setNegativeButton( + "차단" + ) { dialog, _ -> + //글과 그룹 모두 삭제 + userBlock(writerId, writerName) + Toast.makeText(this@ArticleActivity, "해당 유저를 차단하였습니다", Toast.LENGTH_SHORT).show() + val intent = Intent(this@ArticleActivity,MainActivity::class.java) + startActivity(intent) + finish() + dialog.dismiss() + } + ad.show() } else -> { //뒤로가기 @@ -216,6 +241,17 @@ class ArticleActivity : AppCompatActivity() { return super.onOptionsItemSelected(item) } + private fun userBlock(writerId: String, writerName:String) { + val blockId = currentUserBlockRef.push().key.toString() + + val block = mutableMapOf() + block[USER_ID] = writerId + block[USER_NAME] = writerName + + currentUserBlockRef.child(blockId).updateChildren(block) + } + + private fun deleteArticle() { currentArticleRef.setValue(null) currentGroupRef.setValue(null) @@ -303,6 +339,7 @@ class ArticleActivity : AppCompatActivity() { if (articleModel != null) { writerId = articleModel.writerId + writerName = articleModel.writerName articleTitle = articleModel.articleTitle if (articleModel.articleImageUrl.isEmpty()) { val scrollParams = LinearLayout.LayoutParams( diff --git a/app/src/main/java/kr/ac/konkuk/koogle/DBKeys.kt b/app/src/main/java/kr/ac/konkuk/koogle/DBKeys.kt index 43abfa6..c9f75ca 100644 --- a/app/src/main/java/kr/ac/konkuk/koogle/DBKeys.kt +++ b/app/src/main/java/kr/ac/konkuk/koogle/DBKeys.kt @@ -10,6 +10,7 @@ class DBKeys { const val USER_EMAIL = "userEmail" const val USER_PROFILE_IMAGE_URL = "userProfileImageUrl" const val USER_PROFILE_IMAGE_PATH = "profile/photo" + const val DB_BLOCK_USERS= "BlockUsers" //Community, Card const val DB_ARTICLES = "Articles" diff --git a/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CardFragment.kt b/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CardFragment.kt index 8bf8b4d..3b4822f 100644 --- a/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CardFragment.kt +++ b/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CardFragment.kt @@ -1,5 +1,6 @@ package kr.ac.konkuk.koogle.Fragment +import android.app.AlertDialog import android.content.Intent import android.os.Bundle import android.util.Log @@ -15,17 +16,22 @@ import com.google.firebase.database.ktx.database import com.google.firebase.ktx.Firebase import com.yuyakaido.android.cardstackview.* import kr.ac.konkuk.koogle.Activity.ArticleActivity +import kr.ac.konkuk.koogle.Activity.LogInActivity +import kr.ac.konkuk.koogle.Activity.MainActivity import kr.ac.konkuk.koogle.Adapter.CardAdapter +import kr.ac.konkuk.koogle.DBKeys import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_ID import kr.ac.konkuk.koogle.DBKeys.Companion.DB_ARTICLES import kr.ac.konkuk.koogle.DBKeys.Companion.DB_MAIN_TAGS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_USERS import kr.ac.konkuk.koogle.DBKeys.Companion.WRITER_ID import kr.ac.konkuk.koogle.Model.ArticleModel +import kr.ac.konkuk.koogle.Model.BlockUserModel import kr.ac.konkuk.koogle.Model.CardModel +import kr.ac.konkuk.koogle.R import kr.ac.konkuk.koogle.databinding.FragmentCardBinding -class CardFragment : Fragment(), CardStackListener { +class CardFragment : Fragment(R.layout.fragment_card), CardStackListener { var binding: FragmentCardBinding? = null @@ -33,6 +39,8 @@ class CardFragment : Fragment(), CardStackListener { private val cardList = mutableListOf() + private var blockList = mutableListOf() + private val auth: FirebaseAuth by lazy { Firebase.auth } @@ -43,15 +51,25 @@ class CardFragment : Fragment(), CardStackListener { Firebase.database.reference.child(DB_ARTICLES) } + private val currentUserRef: DatabaseReference by lazy { + Firebase.database.reference.child(DB_USERS).child(firebaseUser.uid) + } + + private val currentUserBlockRef: DatabaseReference by lazy { + currentUserRef.child(DBKeys.DB_BLOCK_USERS) + } + private val listener = object : ChildEventListener { override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) { - if (snapshot.child(WRITER_ID).value != firebaseUser.uid) - { + if (snapshot.child(WRITER_ID).value != firebaseUser.uid) { val cardModel = snapshot.getValue(CardModel::class.java) - if (cardModel != null) { + ?: return + + if(!blockList.contains(cardModel.writerId)){ cardModel.tagList = snapshot.child(DB_MAIN_TAGS) cardList.add(cardModel) } + cardAdapter.submitList(cardList) cardAdapter.notifyDataSetChanged() } @@ -67,18 +85,64 @@ class CardFragment : Fragment(), CardStackListener { CardStackLayoutManager(context, this) } - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - // Inflate the layout for this fragment - binding = FragmentCardBinding.inflate(layoutInflater, container, false) +// override fun onCreateView( +// inflater: LayoutInflater, container: ViewGroup?, +// savedInstanceState: Bundle? +// ): View { +// // Inflate the layout for this fragment +// binding = FragmentCardBinding.inflate(layoutInflater, container, false) +// +// initDB() +// +//// initCardStackView() +//// cardRef.addChildEventListener(listener) +// +// return binding!!.root +// } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding = FragmentCardBinding.bind(view) + + if(auth.currentUser != null) { + Log.i("Community fragment", "onViewCreated: ${firebaseUser.uid}") + initDB() +// initRecyclerView() +// initButton() +// +// //데이터를 가져옴 +// //addSingleValueListener -> 즉시성, 1회만 호출 +// //addChildEventListener -> 한번 등록해놓으면 계속 이벤트가 발생할때마다 등록이된다. +// //activity 의 경우 activity 가 종료되면 이벤트가 다 날라가고 view 가 다 destroy 됨 +// //fragment 는 재사용이 되기때문에 onviewcreated 가 호출될때마다 중복으로 데이터를 가져오게됨 +// //따라서 eventlistener 를 전역으로 정의를 해놓고 viewcreated 될때마다 attach 를 하고 destroy 가 될때마다 remove 를 해주는 방식을 채택 +// articleRef.addChildEventListener(listener) + } + else { + val intent = Intent(context, LogInActivity::class.java) + activity?.startActivity(intent) + } + } + private fun initDB() { + currentUserBlockRef.addListenerForSingleValueEvent(object : ValueEventListener { + override fun onDataChange(dataSnapshot: DataSnapshot) { + for (snapshot in dataSnapshot.children) { + val blockUserModel = snapshot.getValue(BlockUserModel::class.java) + if (blockUserModel != null) { + blockList.add(blockUserModel.userId) + } + } + initCardStackView() + cardRef.addChildEventListener(listener) + + } + - initCardStackView() + override fun onCancelled(error: DatabaseError) { - cardRef.addChildEventListener(listener) + } - return binding!!.root + }) } private fun initCardStackView() { @@ -91,20 +155,20 @@ class CardFragment : Fragment(), CardStackListener { manager.setTranslationInterval(8.0f) manager.setSwipeThreshold(0.1f) - cardAdapter.itemClickListener = object: CardAdapter.OnItemClickListener{ + cardAdapter.itemClickListener = object : CardAdapter.OnItemClickListener { override fun onItemChecked( holder: CardAdapter.ViewHolder, view: View, data: CardModel, position: Int ) { - if(auth.currentUser != null) { + if (auth.currentUser != null) { val intent = Intent(context, ArticleActivity::class.java) intent.putExtra(ARTICLE_ID, data.articleId) //fragment 에서 다른 액티비티로 데이터 전달 activity?.startActivity(intent) - }else { + } else { //로그인을 안한 상태 Toast.makeText(context, "로그인 후 사용해주세요", Toast.LENGTH_LONG).show() } @@ -116,18 +180,49 @@ class CardFragment : Fragment(), CardStackListener { data: CardModel, position: Int ) { - //todo 구현 + //dialog 한번 뿌리고 진짜 삭제 + val ad = AlertDialog.Builder(context) + ad.setMessage("해당 유저를 차단하시겠습니까? \n차단하시면 해당 유저의 글을 볼 수 없습니다.") + ad.setPositiveButton( + "취소" + ) { dialog, _ -> + dialog.dismiss() + } + ad.setNegativeButton( + "차단" + ) { dialog, _ -> + //글과 그룹 모두 삭제 + userBlock(data.writerId, data.writerName) + Toast.makeText(context, "해당 유저를 차단하였습니다", Toast.LENGTH_SHORT).show() + val intent = Intent(context, MainActivity::class.java) + startActivity(intent) + dialog.dismiss() + } + ad.show() + } } } - override fun onResume() { - super.onResume() + private fun userBlock(writerId: String, writerName: String) { + val blockId = currentUserBlockRef.push().key.toString() + + val block = mutableMapOf() + block[DBKeys.USER_ID] = writerId + block[DBKeys.USER_NAME] = writerName + + currentUserBlockRef.child(blockId).updateChildren(block) - //view가 다시 보일때마다 뷰를 다시 그림 - cardAdapter.notifyDataSetChanged() } + +// override fun onResume() { +// super.onResume() +// +// //view가 다시 보일때마다 뷰를 다시 그림 +// cardAdapter.notifyDataSetChanged() +// } + override fun onDestroyView() { super.onDestroyView() diff --git a/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CommunityFragment.kt b/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CommunityFragment.kt index 95af30e..185a1f3 100644 --- a/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CommunityFragment.kt +++ b/app/src/main/java/kr/ac/konkuk/koogle/Fragment/CommunityFragment.kt @@ -28,10 +28,13 @@ import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_CONTENT import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_ID import kr.ac.konkuk.koogle.DBKeys.Companion.ARTICLE_TITLE import kr.ac.konkuk.koogle.DBKeys.Companion.DB_ARTICLES +import kr.ac.konkuk.koogle.DBKeys.Companion.DB_BLOCK_USERS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_MAIN_TAGS import kr.ac.konkuk.koogle.DBKeys.Companion.DB_USERS import kr.ac.konkuk.koogle.DBKeys.Companion.SUB_TAGS import kr.ac.konkuk.koogle.Model.ArticleModel +import kr.ac.konkuk.koogle.Model.BlockUserModel +import kr.ac.konkuk.koogle.Model.GroupModel import kr.ac.konkuk.koogle.Model.TagModel import kr.ac.konkuk.koogle.R import kr.ac.konkuk.koogle.databinding.FragmentCommunityBinding @@ -43,6 +46,8 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { private lateinit var communityAdapter: CommunityAdapter + private var blockList = mutableListOf() + private val articleList = mutableListOf() private var searchedArticleList = mutableListOf() @@ -54,6 +59,13 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { private val articleRef: DatabaseReference by lazy { Firebase.database.reference.child(DB_ARTICLES) } + private val currentUserRef: DatabaseReference by lazy { + Firebase.database.reference.child(DB_USERS).child(firebaseUser.uid) + } + + private val currentUserBlockRef: DatabaseReference by lazy { + currentUserRef.child(DB_BLOCK_USERS) + } private val listener = object : ChildEventListener { override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) { @@ -61,7 +73,11 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { val articleModel = snapshot.getValue(ArticleModel::class.java) articleModel ?: return - articleList.add(0, articleModel) //최신글이 위로 올라오도록 + if (!blockList.contains(articleModel.writerId)) { + //최신글이 위로 올라오도록 + articleList.add(0, articleModel) + } + communityAdapter.submitList(articleList) communityAdapter.notifyDataSetChanged() } @@ -104,16 +120,17 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { if(auth.currentUser != null) { Log.i("Community fragment", "onViewCreated: ${firebaseUser.uid}") - initRecyclerView() - initButton() - - //데이터를 가져옴 - //addSingleValueListener -> 즉시성, 1회만 호출 - //addChildEventListener -> 한번 등록해놓으면 계속 이벤트가 발생할때마다 등록이된다. - //activity 의 경우 activity 가 종료되면 이벤트가 다 날라가고 view 가 다 destroy 됨 - //fragment 는 재사용이 되기때문에 onviewcreated 가 호출될때마다 중복으로 데이터를 가져오게됨 - //따라서 eventlistener 를 전역으로 정의를 해놓고 viewcreated 될때마다 attach 를 하고 destroy 가 될때마다 remove 를 해주는 방식을 채택 - articleRef.addChildEventListener(listener) + initDB() +// initRecyclerView() +// initButton() +// +// //데이터를 가져옴 +// //addSingleValueListener -> 즉시성, 1회만 호출 +// //addChildEventListener -> 한번 등록해놓으면 계속 이벤트가 발생할때마다 등록이된다. +// //activity 의 경우 activity 가 종료되면 이벤트가 다 날라가고 view 가 다 destroy 됨 +// //fragment 는 재사용이 되기때문에 onviewcreated 가 호출될때마다 중복으로 데이터를 가져오게됨 +// //따라서 eventlistener 를 전역으로 정의를 해놓고 viewcreated 될때마다 attach 를 하고 destroy 가 될때마다 remove 를 해주는 방식을 채택 +// articleRef.addChildEventListener(listener) } else { val intent = Intent(context, LogInActivity::class.java) @@ -121,6 +138,35 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { } } + private fun initDB() { + currentUserBlockRef.addListenerForSingleValueEvent(object: ValueEventListener{ + override fun onDataChange(dataSnapshot: DataSnapshot) { + for(snapshot in dataSnapshot.children){ + val blockUserModel = snapshot.getValue(BlockUserModel::class.java) + if (blockUserModel != null) { + blockList.add(blockUserModel.userId) + } + } + initRecyclerView() + initButton() + + //데이터를 가져옴 + //addSingleValueListener -> 즉시성, 1회만 호출 + //addChildEventListener -> 한번 등록해놓으면 계속 이벤트가 발생할때마다 등록이된다. + //activity 의 경우 activity 가 종료되면 이벤트가 다 날라가고 view 가 다 destroy 됨 + //fragment 는 재사용이 되기때문에 onviewcreated 가 호출될때마다 중복으로 데이터를 가져오게됨 + //따라서 eventlistener 를 전역으로 정의를 해놓고 viewcreated 될때마다 attach 를 하고 destroy 가 될때마다 remove 를 해주는 방식을 채택 + articleRef.addChildEventListener(listener) + } + + + override fun onCancelled(error: DatabaseError) { + + } + + }) + } + private fun initRecyclerView() { articleList.clear() //초기화 코드 @@ -274,12 +320,12 @@ class CommunityFragment : Fragment(R.layout.fragment_community) { } } - override fun onResume() { - super.onResume() - - //view가 다시 보일때마다 뷰를 다시 그림 - communityAdapter.notifyDataSetChanged() - } +// override fun onResume() { +// super.onResume() +// +// //view가 다시 보일때마다 뷰를 다시 그림 +// communityAdapter.notifyDataSetChanged() +// } override fun onDestroyView() { super.onDestroyView() diff --git a/app/src/main/java/kr/ac/konkuk/koogle/Model/UserModel.kt b/app/src/main/java/kr/ac/konkuk/koogle/Model/UserModel.kt index ee9efa1..37bc09f 100644 --- a/app/src/main/java/kr/ac/konkuk/koogle/Model/UserModel.kt +++ b/app/src/main/java/kr/ac/konkuk/koogle/Model/UserModel.kt @@ -6,7 +6,8 @@ data class UserModel( val userName: String, //유저 이름 val userProfileImageUrl: String, // 유저 프로필 이미지 url val Groups: GroupModel?, //유저가 속한 그룹들 모델 - val Comments: CommentModel? //유저가 받은 평가 + val Comments: CommentModel?, //유저가 받은 평가 + val blockList: BlockUserModel? ) { - constructor() : this("", "", "", "", null, null) + constructor() : this("", "", "", "", null, null, null) }