Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ reviews:
profile: assertive
auto_review:
enabled: true
base_branches:
- "develop"
drafts: false
auto_incremental_review: false
tools:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/coderabbit-ready-for-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Request CodeRabbit review

on:
pull_request:
branches: [develop]
types: [ready_for_review]

permissions:
issues: write

jobs:
request-review:
runs-on: ubuntu-latest
steps:
- name: Request full review
run: gh pr comment "$PR_URL" --body '@coderabbitai full review'
env:
GH_TOKEN: ${{ github.token }}
PR_URL: ${{ github.event.pull_request.html_url }}
14 changes: 14 additions & 0 deletions Tekken8 Frame Data/TK8.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
AD8700000000000000000001 /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = AD8700000000000000000002 /* FirebaseRemoteConfig */; };
E48DD6EE2D78738A000308CC /* PostgREST in Frameworks */ = {isa = PBXBuildFile; productRef = E48DD6ED2D78738A000308CC /* PostgREST */; };
E48DD6F02D78738A000308CC /* Storage in Frameworks */ = {isa = PBXBuildFile; productRef = E48DD6EF2D78738A000308CC /* Storage */; };
E48DD6F32D787391000308CC /* Supabase in Frameworks */ = {isa = PBXBuildFile; productRef = E48DD6F22D787391000308CC /* Supabase */; };
Expand Down Expand Up @@ -94,6 +95,7 @@
E4E2D9FC2E670CBB003DCB4F /* FirebaseAnalyticsIdentitySupport in Frameworks */,
E48DD6EE2D78738A000308CC /* PostgREST in Frameworks */,
E4E2D9F82E670CBB003DCB4F /* FirebaseAnalytics in Frameworks */,
AD8700000000000000000001 /* FirebaseRemoteConfig in Frameworks */,
E48DD6F32D787391000308CC /* Supabase in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -160,6 +162,7 @@
E48DD6F22D787391000308CC /* Supabase */,
E4D6BF502E6582480091C030 /* GoogleMobileAds */,
E4E2D9F72E670CBB003DCB4F /* FirebaseAnalytics */,
AD8700000000000000000002 /* FirebaseRemoteConfig */,
E4E2D9F92E670CBB003DCB4F /* FirebaseAnalyticsCore */,
E4E2D9FB2E670CBB003DCB4F /* FirebaseAnalyticsIdentitySupport */,
);
Expand Down Expand Up @@ -415,6 +418,9 @@
E4024B412D3F399F007C855C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ADMOB_APP_ID = "ca-app-pub-3866042653915701~9914634913";
ADMOB_BANNER_AD_UNIT_ID = "ca-app-pub-3866042653915701/3419960087";
ADMOB_NATIVE_AD_UNIT_ID = "ca-app-pub-3866042653915701/4686004711";
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
Expand Down Expand Up @@ -480,6 +486,9 @@
E4024B422D3F399F007C855C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ADMOB_APP_ID = "ca-app-pub-3866042653915701~9914634913";
ADMOB_BANNER_AD_UNIT_ID = "ca-app-pub-3866042653915701/3419960087";
ADMOB_NATIVE_AD_UNIT_ID = "ca-app-pub-3866042653915701/4686004711";
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
Expand Down Expand Up @@ -690,6 +699,11 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
AD8700000000000000000002 /* FirebaseRemoteConfig */ = {
isa = XCSwiftPackageProductDependency;
package = E4E2D9F62E670CBB003DCB4F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseRemoteConfig;
};
E48DD6ED2D78738A000308CC /* PostgREST */ = {
isa = XCSwiftPackageProductDependency;
package = E48DD6EC2D78738A000308CC /* XCRemoteSwiftPackageReference "supabase-swift" */;
Expand Down
7 changes: 4 additions & 3 deletions Tekken8 Frame Data/TK8/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let isDebugBuild = false
#endif

if TK8AnalyticsCollectionPolicy.shouldCollect(
let collectAnalytics = TK8AnalyticsCollectionPolicy.shouldCollect(
isDebugBuild: isDebugBuild,
launchArguments: ProcessInfo.processInfo.arguments
) {
)
if collectAnalytics {
FirebaseApp.configure()
Analytics.setAnalyticsCollectionEnabled(true)
Analytics.setAnalyticsCollectionEnabled(collectAnalytics)
}
}
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ final class CharacterListViewController: BaseViewController {
private let searchAnalyticsTracker: SearchAnalyticsTracker
private var hasLoadedCharacters = false
private var shouldLogMemoEntryImpression = true
private var pendingImageKeys = Set<String>()

private let preference: CharacterLayoutPreference
private var currentLayoutMode: CharacterCollectionViewMode
Expand Down Expand Up @@ -88,6 +89,7 @@ final class CharacterListViewController: BaseViewController {

private func recordVisibleScreen() {
guard presentedViewController == nil else { return }
bannerAdHost?.appear()
analytics.log(.screenViewed(.characterList))
if shouldLogMemoEntryImpression {
analytics.log(.memoEntryImpression())
Expand Down Expand Up @@ -136,7 +138,7 @@ final class CharacterListViewController: BaseViewController {
}

@objc private func settingsButtonTapped() {
let settingsViewController = SettingViewController(analytics: analytics)
let settingsViewController = container.makeSettingViewController()
navigationController?.pushViewController(settingsViewController, animated: true)
}

Expand Down Expand Up @@ -192,6 +194,12 @@ final class CharacterListViewController: BaseViewController {
self?.updateSnapshot(for: filteredCharacters)
}
.store(in: &subscriptionSet)

characterListViewModel.characterImagesPublisher
.sink { [weak self] images in
self?.reconfigureCharacters(with: images)
}
.store(in: &subscriptionSet)
}

private func fetchCharacters() {
Expand Down Expand Up @@ -262,16 +270,14 @@ private extension CharacterListViewController {
cell.contentConfiguration = UIHostingConfiguration {
CharacterCell(
character: itemIdentifier,
characterImagePublisher: self.characterListViewModel.characterImagesPublisher,
characterImages: self.characterListViewModel.characterImages
image: self.characterListViewModel.image(for: itemIdentifier.nameEN)
)
}
case .grid:
cell.contentConfiguration = UIHostingConfiguration {
CharacterGridCell(
character: itemIdentifier,
characterImagePublisher: self.characterListViewModel.characterImagesPublisher,
characterImages: self.characterListViewModel.characterImages
image: self.characterListViewModel.image(for: itemIdentifier.nameEN)
)
}
}
Expand All @@ -291,9 +297,21 @@ private extension CharacterListViewController {

let attemptID = searchAnalyticsTracker.attemptID
dataSource?.apply(snapshot, animatingDifferences: false) { [weak self] in
self?.searchAnalyticsTracker.resultsApplied(count: characters.count, for: attemptID)
guard let self else { return }
self.searchAnalyticsTracker.resultsApplied(count: characters.count, for: attemptID)
self.reconfigureCharacters(with: self.characterListViewModel.characterImages)
}
}

func reconfigureCharacters(with images: [String: UIImage]) {
pendingImageKeys.formUnion(images.keys)
guard !pendingImageKeys.isEmpty, var snapshot = dataSource?.snapshot() else { return }
let items = snapshot.itemIdentifiers.filter { pendingImageKeys.contains($0.nameEN) }
guard !items.isEmpty else { return }
pendingImageKeys.subtract(items.map(\.nameEN))
snapshot.reconfigureItems(items)
dataSource?.apply(snapshot, animatingDifferences: false)
}
}

// MARK: - UICollectionViewDelegate Conformance
Expand Down
14 changes: 3 additions & 11 deletions Tekken8 Frame Data/TK8/Character/View/Cell/CharacterCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Created by 문영균 on 3/28/25.
//

import Combine
import Foundation
import SwiftUI

Expand All @@ -19,8 +18,7 @@ struct CharacterCell: View, ReuseIdentifiable {
return (character.nameEN, nil)
}
}
let characterImagePublisher: AnyPublisher<[String : UIImage], Never>
@State var characterImages: [String: UIImage]
let image: UIImage?

var body: some View {
HStack(alignment: .center, spacing: 12) {
Expand All @@ -46,9 +44,6 @@ struct CharacterCell: View, ReuseIdentifiable {
.foregroundStyle(.white.opacity(0.3))
.padding(.trailing, 4)
}
.onReceive(characterImagePublisher) { images in
characterImages = images
}
.padding(6)
.background(
RoundedRectangle(cornerRadius: 14)
Expand All @@ -62,9 +57,7 @@ struct CharacterCell: View, ReuseIdentifiable {

@ViewBuilder
private var characterImage: some View {
let img = characterImages[character.nameEN]

Image(uiImage: img ?? UIImage(named: "mokujin")!)
Image(uiImage: image ?? UIImage(named: "mokujin")!)
.resizable()
.scaledToFill()
.frame(
Expand All @@ -89,7 +82,6 @@ private enum Constants {
#Preview {
CharacterCell(
character: Character(id: 1, nameEN: "Nina Williams", nameKR: "니나 윌리엄스", imageURL: "https://i.ibb.co/GXN7B5k/nina.png"),
characterImagePublisher: Empty().eraseToAnyPublisher(),
characterImages: [:],
image: nil
)
}
14 changes: 3 additions & 11 deletions Tekken8 Frame Data/TK8/Character/View/Cell/CharacterGridCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
// TK8
//

import Combine
import Foundation
import SwiftUI

struct CharacterGridCell: View, ReuseIdentifiable {
var character: Character
let characterImagePublisher: AnyPublisher<[String: UIImage], Never>
@State var characterImages: [String: UIImage]
let image: UIImage?

private var localizedName: String {
let preferredLanguage = Bundle.main.preferredLocalizations.first
Expand Down Expand Up @@ -50,15 +48,10 @@ struct CharacterGridCell: View, ReuseIdentifiable {
.stroke(.white.opacity(0.12), lineWidth: 0.5)
)
}
.onReceive(characterImagePublisher) { images in
characterImages = images
}
}

private var characterImage: some View {
let img = characterImages[character.nameEN]

return Image(uiImage: img ?? UIImage(named: "mokujin")!)
Image(uiImage: image ?? UIImage(named: "mokujin")!)
.resizable()
.scaledToFill()
}
Expand All @@ -81,8 +74,7 @@ private enum Constants {
nameKR: "니나 윌리엄스",
imageURL: "https://i.ibb.co/GXN7B5k/nina.png"
),
characterImagePublisher: Empty().eraseToAnyPublisher(),
characterImages: [:]
image: nil
)
.frame(width: 120, height: 160)
.background(Color(uiColor: .tkBackground)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final class CharacterSelectViewController: BaseViewController {
private let characterSelectView: CharacterCollectionView
private let searchController: UISearchController
private var dataSource: CharacterDataSource?
private var pendingImageKeys = Set<String>()
weak var delegate: Selectable?

private let currentLayoutMode: CharacterCollectionViewMode
Expand Down Expand Up @@ -63,6 +64,13 @@ final class CharacterSelectViewController: BaseViewController {
self?.updateSnapshot(for: characters)
}
.store(in: &subscriptionSet)

viewModel.characterImagesPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] images in
self?.reconfigureCharacters(with: images)
}
.store(in: &subscriptionSet)
}

override func setupDataSource() {
Expand Down Expand Up @@ -126,16 +134,14 @@ private extension CharacterSelectViewController {
cell.contentConfiguration = UIHostingConfiguration{
CharacterCell(
character: itemIdentifier,
characterImagePublisher: self.viewModel.characterImagesPublisher,
characterImages: self.viewModel.characterImages
image: self.viewModel.image(for: itemIdentifier.nameEN)
)
}
case .grid:
cell.contentConfiguration = UIHostingConfiguration{
CharacterGridCell(
character: itemIdentifier,
characterImagePublisher: self.viewModel.characterImagesPublisher,
characterImages: self.viewModel.characterImages
image: self.viewModel.image(for: itemIdentifier.nameEN)
)
}
}
Expand All @@ -148,6 +154,19 @@ private extension CharacterSelectViewController {
var snapshot = Snapshot()
snapshot.appendSections([.main])
snapshot.appendItems(characters, toSection: .main)
dataSource?.apply(snapshot, animatingDifferences: false) { [weak self] in
guard let self else { return }
self.reconfigureCharacters(with: self.viewModel.characterImages)
}
}

func reconfigureCharacters(with images: [String: UIImage]) {
pendingImageKeys.formUnion(images.keys)
guard !pendingImageKeys.isEmpty, var snapshot = dataSource?.snapshot() else { return }
let items = snapshot.itemIdentifiers.filter { pendingImageKeys.contains($0.nameEN) }
guard !items.isEmpty else { return }
pendingImageKeys.subtract(items.map(\.nameEN))
snapshot.reconfigureItems(items)
dataSource?.apply(snapshot, animatingDifferences: false)
}
}
Expand Down
15 changes: 15 additions & 0 deletions Tekken8 Frame Data/TK8/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GADApplicationIdentifier</key>
<string>$(ADMOB_APP_ID)</string>
<key>AdMobBannerAdUnitID</key>
<string>$(ADMOB_BANNER_AD_UNIT_ID)</string>
<key>AdMobNativeAdUnitID</key>
<string>$(ADMOB_NATIVE_AD_UNIT_ID)</string>
<key>GADDelayAppMeasurementInit</key>
<true/>
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
<key>API_KEY</key>
<string>$(API_KEY)</string>
<key>CFBundleDocumentTypes</key>
Expand Down
Loading
Loading