Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum AmplitudeEventType: String {
case clickShortcutButton = "click_link.btn"
case clickReadAllButton = "click_allread.btn"
case clickNotificationItem = "click_notification_item"
case clickCoffeeChat = "at38_playground_coffee_chat" // 먼저 배포된 안드로이드 컨벤션에 맞춤. 앰플리튜드 tf 개설 후 click_으로 통일하여 사용할 예정

// 신규 홈 클릭 이벤트
case clickAllCalendar = "click_all_calendar"
Expand Down
6 changes: 3 additions & 3 deletions SOPT-iOS/Projects/Core/Sources/Enum/ServiceType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public enum ServiceType {
case member
case group
case instagram
case playgroundCommunity
case coffeechat

public var serviceDomainLink: String {
switch self {
case .officialHomepage: return ExternalURL.SOPT.officialHomepage
Expand All @@ -31,7 +31,7 @@ public enum ServiceType {
case .member: return ExternalURL.Playground.member
case .group: return ExternalURL.Playground.group
case .instagram: return ExternalURL.SNS.instagram
case .playgroundCommunity: return ExternalURL.Playground.playgroundCommunity
case .coffeechat: return ExternalURL.Playground.coffeechat
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

public extension ServiceType {
var toAmplitudeEventType: AmplitudeEventType {
var toAmplitudeEventType: AmplitudeEventType? {
switch self {
case .officialHomepage: return .clickOfficialHomepage
case .review: return .clickReview
Expand All @@ -20,7 +20,7 @@ public extension ServiceType {
case .member: return .clickMember
case .group: return .clickMoim
case .instagram: return .clickInstagram
case .playgroundCommunity: return .clickPlaygroundCommunity
case .coffeechat: return .clickCoffeeChat
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions SOPT-iOS/Projects/Core/Sources/Literals/ExternalURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ public struct ExternalURL {
public static let project = "\(main)/projects"
public static let member = "\(main)/members"
public static let group = "\(main)/group?utm_source=playground_group&utm_medium=app_button&utm_campaign=app"
public static let playgroundCommunity = main
public static let feed = "\(main)/feed/upload"
public static let feedUpload = "\(main)/feed/upload"
public static let feed = "\(main)/feed"
Comment on lines +51 to +52
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# ExternalURL.Playground.feed / feedUpload 사용처 확인
rg -nP --type=swift '\bExternalURL\.Playground\.(feed|feedUpload)\b' -C2

Repository: sopt-makers/SOPT-iOS

Length of output: 2405


ExternalURL.Playground.feed 경로 변경 영향 범위 점검 필요

ExternalURL.Playground.feedHomeFeature/Sources/HomeScene/ViewModel/HomeForMemberViewModel.swift:208(“전체 보기” 버튼)에서만 사용되고, 업로드 경로는 feedUpload를 쓰는 HomeFeature/Sources/HomeScene/Views/FABButton/MenuSectionItem.swift:49, TabBarFeature/Sources/FABButton/MenuSectionItem.swift:49에서만 처리됩니다.
다만 onViewAllContentButtonTapped 구현이 실제로 “전체 보기(/feed)”가 아니라 “업로드 진입(/feed/upload)”을 기대하는 흐름인지 확인이 필요합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SOPT-iOS/Projects/Core/Sources/Literals/ExternalURL.swift` around lines 51 -
52, ExternalURL.Playground.feed currently points to "/feed" but usages suggest a
mismatch with the upload route; inspect
HomeForMemberViewModel.onViewAllContentButtonTapped and the MenuSectionItem uses
of ExternalURL.Playground.feedUpload, confirm whether the "전체 보기" action should
navigate to ExternalURL.Playground.feed or to ExternalURL.Playground.feedUpload,
and then update the call site(s) accordingly (either change the constant used in
HomeForMemberViewModel to feedUpload or keep feed and adjust any
expectations/handlers that assume upload). Also run a quick search for
ExternalURL.Playground.feed and feedUpload to ensure no other callers are
relying on the old mapping and update tests or navigation logic as needed.

public static let blog = "\(main)/blog"
public static let makeGroup = "\(main)/group/make"
public static let makeLightGroup = "\(main)/group/make/flash"
public static let makeGroupFeed = "\(main)/group?modal=create-feed"
public static let editProfile = "\(main)/members/edit"
public static let coffeechat = "\(main)/coffeechat"
}
}
5 changes: 3 additions & 2 deletions SOPT-iOS/Projects/Core/Sources/Literals/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,18 @@ public struct I18N {

public struct MainProduct {
public static let headerTitleForVisitor = "SOPT를 더 알고 싶다면, 둘러보세요"
public static let playground = "Playground"
public static let soptPlayground = "SOPT Playground"
public static let groupAndStudy = "모임/스터디"
public static let member = "멤버"
public static let project = "프로젝트"
public static let coffeechat = "커피솝"
public static let homePage = "홈페이지"
public static let activityReview = "활동후기"
public static let instagram = "인스타그램"
}

public struct PopularPosts {
public static let headerTitle = "실시간 인기글"
public static let headerTitle = "지금 인기 소식"
public static let morePosts = "다른 게시물 보러가기"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Core

enum HomeAmplitudeEventPropertyValue: String, AmplitudeEventPropertyValueConvertible {
case latestPosts = "latest_posts"
case popularPosts = "popular_posts"
case realTimeFeed = "realtime_feed"
case homeBanner = "home_banner"
case homeFAB = "home_fab"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,25 +96,33 @@ extension HomeForMemberVC {
}

private func createMainProductSection() -> NSCollectionLayoutSection {
/// header: SOPT Playground
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(30))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize,
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top)

/// item: 프로덕트 카드
let productItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.25),
heightDimension: .absolute(92))
let productItem = NSCollectionLayoutItem(layoutSize: productItemSize)

/// group: 프로덕트 카드
let productGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(92))
let productGroup = NSCollectionLayoutGroup.horizontal(layoutSize: productGroupSize,
subitems: [productItem])
productGroup.interItemSpacing = .fixed(Metric.productItemSpacing)

/// section 지정
let section = NSCollectionLayoutSection(group: productGroup)
section.contentInsets = NSDirectionalEdgeInsets(top: Metric.defaultItemSpacing,
section.boundarySupplementaryItems = [header]
section.contentInsets = NSDirectionalEdgeInsets(top: 12,
leading: Metric.collectionViewDefaultSideInset,
bottom: Metric.mainProductSectionSpacing,
trailing: Metric.collectionViewDefaultSideInset)

return section
}

Expand Down Expand Up @@ -156,12 +164,12 @@ extension HomeForMemberVC {
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top)

/// item: 실시간 인기글
/// item: 지금 인기 소식
let popularPostsItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(122))
let popularPostsItem = NSCollectionLayoutItem(layoutSize: popularPostsItemSize)

/// group: 실시간 인기글
/// group: 지금 인기 소식
let popularPostsGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(122))
let popularPostsGroup = NSCollectionLayoutGroup.vertical(layoutSize: popularPostsGroupSize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import Foundation

protocol HomeSectionUIConfigurable {
var headerTitle: String { get }
var shouldShowFireIcon: Bool { get } // fire 아이콘의 유무
var shouldShowViewAllContentButton: Bool { get } // 전체보기 버튼의 유무
var shouldShowFireIcon: Bool { get }
var shouldShowViewAllContentButton: Bool { get }
var isSubSectionHeader: Bool { get }
}

extension HomeSectionUIConfigurable {
var isSubSectionHeader: Bool { return false }
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ extension HomeForMemberVC {
headerView.viewAllContentButtonTap
.withUnretained(self)
.sink { owner, _ in
owner.viewAllButtonTapped.send()
owner.viewAllButtonTapped.send(sectionKind)
}
.store(in: headerView.cancelBag)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ enum HomeForMemberSectionLayoutKind: Int, CaseIterable {
extension HomeForMemberSectionLayoutKind: HomeSectionUIConfigurable {
var headerTitle: String {
switch self {
case .mainProduct:
return I18N.Home.MainProduct.soptPlayground
case .popularPosts:
return I18N.Home.PopularPosts.headerTitle
case .latestPosts:
Expand All @@ -31,12 +33,16 @@ extension HomeForMemberSectionLayoutKind: HomeSectionUIConfigurable {
return ""
}
}

var shouldShowFireIcon: Bool {
return self == .popularPosts
}

var shouldShowViewAllContentButton: Bool {
return self == .latestPosts
return self == .popularPosts || self == .latestPosts
}

var isSubSectionHeader: Bool {
return self == .mainProduct
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class HomeForMemberVC: UIViewController, HomeForMemberViewControllable {
private var cellTapped = PassthroughSubject<HomeForMemberItem, Never>()
private(set) var attendanceButtonTapped = PassthroughSubject<Void, Never>()
private(set) var surveyButtonTapped = PassthroughSubject<Void, Never>()
private(set) var viewAllButtonTapped = PassthroughSubject<Void, Never>()
private(set) var viewAllButtonTapped = PassthroughSubject<HomeForMemberSectionLayoutKind, Never>()
private var socialLinkButtonTapped = PassthroughSubject<HomePresentationModel.SocialLink, Never>()
private(set) var profileImageViewTapped = PassthroughSubject<PostInfo, Never>()
private(set) var profileEditTapped = PassthroughSubject<Void, Never>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public class HomeForMemberViewModel: HomeForMemberViewModelType {
@Published private(set) var isFABTapped: Bool = false

let productServiceList: [HomePresentationModel.ProductService] = [
.init(product: .playgroundCommunity),
.init(product: .group),
.init(product: .member),
.init(product: .project)
.init(product: .group),
.init(product: .project),
.init(product: .coffeechat)
]

let socialLinkList: [HomePresentationModel.SocialLink] = [
Expand All @@ -60,7 +60,7 @@ public class HomeForMemberViewModel: HomeForMemberViewModelType {
let extendedFloatingButtonTapped: Driver<Void>
let surveyButtonTapped: Driver<Void>
let socialLinkButtonTapped: Driver<HomePresentationModel.SocialLink>
let viewAllButtonTapped: Driver<Void>
let viewAllButtonTapped: Driver<HomeForMemberSectionLayoutKind>
let profileImageViewTapped: Driver<PostInfo>
let editProfileTapped: Driver<Void>
}
Expand Down Expand Up @@ -204,9 +204,10 @@ extension HomeForMemberViewModel {

input.viewAllButtonTapped
.withUnretained(self)
.sink { owner, _ in
owner.onViewAllContentButtonTapped?(ExternalURL.Playground.main)
owner.eventTracker.trackClickViewAll(sectionName: .latestPosts)
.sink { owner, sectionKind in
owner.onViewAllContentButtonTapped?(ExternalURL.Playground.feed)
let sectionName: HomeAmplitudeEventPropertyValue = sectionKind == .popularPosts ? .popularPosts : .latestPosts
owner.eventTracker.trackClickViewAll(sectionName: sectionName)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
.store(in: cancelBag)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ extension ServiceType {
return DSKitAsset.Assets.imgGroupLogo.image
case .instagram:
return DSKitAsset.Assets.imgInstagram.image
case .playgroundCommunity:
return DSKitAsset.Assets.imgPlaygroundLogo.image
case .coffeechat:
return DSKitAsset.Assets.icCoffeechat.image
case .youtube:
return DSKitAsset.Assets.icYoutube.image
default:
Expand All @@ -50,8 +50,8 @@ extension ServiceType {
return I18N.Home.MainProduct.groupAndStudy
case .instagram:
return I18N.Home.MainProduct.instagram
case .playgroundCommunity:
return I18N.Home.MainProduct.playground
case .coffeechat:
return I18N.Home.MainProduct.coffeechat
case .youtube:
return I18N.Home.SocialLink.youtube
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ enum FABMenuSection: CaseIterable, FABMenuSectionProtocol {
case .playground:
return [MenuSectionItem(title: I18N.TabBar.Playground.write,
icon: DSKitAsset.Assets.icFabPencil.image,
url: ExternalURL.Playground.feed)]
url: ExternalURL.Playground.feedUpload)]
case .groupAndStudy:
return [
MenuSectionItem(title: I18N.TabBar.GroupAndStudy.makeGroup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,21 @@ extension HomeDefaultHeaderView {
self.titleLabel.text = sectionKind.headerTitle
self.fireImageView.isHidden = !sectionKind.shouldShowFireIcon
self.viewAllContentButton.isHidden = !sectionKind.shouldShowViewAllContentButton

if sectionKind.isSubSectionHeader {
titleLabel.font = DSKitFontFamily.Suit.semiBold.font(size: 14)
titleLabel.textColor = DSKitAsset.Colors.gray400.color
titleLabel.snp.remakeConstraints { make in
make.leading.equalToSuperview()
make.top.equalToSuperview().offset(12)
}
} else {
titleLabel.font = DSKitFontFamily.Suit.bold.font(size: 20)
titleLabel.textColor = DSKitAsset.Colors.white.color
titleLabel.snp.remakeConstraints { make in
make.leading.equalToSuperview()
make.centerY.equalToSuperview()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ enum FABMenuSection: CaseIterable, FABMenuSectionProtocol {
case .playground:
return [MenuSectionItem(title: I18N.TabBar.Playground.write,
icon: DSKitAsset.Assets.icFabPencil.image,
url: ExternalURL.Playground.feed)]
url: ExternalURL.Playground.feedUpload)]
case .groupAndStudy:
return [
MenuSectionItem(title: I18N.TabBar.GroupAndStudy.makeGroup,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "ic_coffeechat.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.