Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
bf78be3
Merge pull request #244 from Nexters/release/1.0.7
leemhyungyu Sep 17, 2024
2b4169b
feat: BottleAlert Modifier 구현
leemhyungyu Sep 14, 2024
aea3522
feat: ButtonAppearanceType cancel 추가
leemhyungyu Sep 14, 2024
9c1169d
feat: BottleAlertView 구현
leemhyungyu Sep 14, 2024
9c27729
feat: BottleAlert 버튼 속성 수정
leemhyungyu Sep 14, 2024
d592618
chore: warning Image Assets 추가
leemhyungyu Sep 20, 2024
743bf52
style: BottleAlert 네이밍 수정
leemhyungyu Sep 20, 2024
3e71208
feat: BottleAlert 디자인시스템 반영
leemhyungyu Sep 20, 2024
de7755b
Merge pull request #246 from Nexters/feature/#231-커스텀-alert-구현
leemhyungyu Sep 20, 2024
f76b409
feat: ArrowListView 구현
leemhyungyu Sep 2, 2024
36721fe
feat: BottleToggle 구현
leemhyungyu Sep 2, 2024
5b44fdd
feat: ToggleListView 구현
leemhyungyu Sep 2, 2024
85cbd64
feat: ListContainerView 구현
leemhyungyu Sep 2, 2024
c211110
feat: ButtonListView 구현
leemhyungyu Sep 2, 2024
d987ddd
feat: ListView 데모 앱 추가
leemhyungyu Sep 2, 2024
cc8a9eb
feat: ArrowListView arrowButton 사이즈 변경
leemhyungyu Sep 17, 2024
b86b435
feat: 화살표 클릭시 action 실행하도록 수정
leemhyungyu Sep 17, 2024
ffff94b
Revert "feat: 화살표 클릭시 action 실행하도록 수정"
leemhyungyu Sep 20, 2024
7f9a4f3
feat: TextListView 추가
leemhyungyu Sep 20, 2024
32d50dd
Merge pull request #229 from Nexters/feature/#224-listsDesignSystem
leemhyungyu Sep 20, 2024
c8e2995
feat: 마이페이지 변경된 View 구현
leemhyungyu Sep 15, 2024
ef75ba9
Merge pull request #249 from Nexters/feature/#225-마이페이지-리뉴얼-작업
leemhyungyu Sep 20, 2024
3fa8fd7
[Feature/#239] 강제 업데이트 구현 로직 개선 (#250)
JongHoooon Sep 21, 2024
cfc1a97
feat: AlertSettingFeature 생성
leemhyungyu Sep 21, 2024
6272eb4
feat: AlertSettingView 생성
leemhyungyu Sep 21, 2024
856f899
feat: MyPageRoot 구현
leemhyungyu Sep 21, 2024
280da47
feat: MainTab MyPageRootView 화면으로 수정
leemhyungyu Sep 21, 2024
9c5a7d2
feat: 알림 설정 클릭 시 AlertSettingView 화면 전환
leemhyungyu Sep 21, 2024
bcdda5a
feat: 알림 설정 View 구현
leemhyungyu Sep 21, 2024
b59e98d
feat: AlertType 구현
leemhyungyu Sep 21, 2024
e3e562a
feat: AlertStateRequestDTO 구현
leemhyungyu Sep 21, 2024
f0883e5
feat: UserAPI 구현
leemhyungyu Sep 21, 2024
059eae0
feat: AlertState 구현
leemhyungyu Sep 21, 2024
16da510
feat: AlertStateResponseDTO 구현
leemhyungyu Sep 21, 2024
56a1ace
feat: 알림 설정 진입 시 서버로부터 받아온 값으로 화면 표시
leemhyungyu Sep 21, 2024
141e01f
feat: 각 토글 변경 시 API 호출 및 디바운스 설정
leemhyungyu Sep 21, 2024
b8ca2f4
Merge pull request #253 from Nexters/feature/#252-마이페이지-알림설정-구현
leemhyungyu Sep 22, 2024
f58ebaa
feat: AccountSettingFeature 구현
leemhyungyu Sep 21, 2024
9caf4db
feat: AccountSettingView 구현
leemhyungyu Sep 21, 2024
c48cec4
feat: 계정 관리 클릭 시 화면 전환
leemhyungyu Sep 21, 2024
311c5a0
feat: 로그아웃, 탈퇴하기 구현
leemhyungyu Sep 21, 2024
86991de
feat: 매칭 토글 변경 시 API 호출
leemhyungyu Sep 21, 2024
882e7eb
feat: 계정관리 진입 시 매칭 활성화 여부 동기화
leemhyungyu Sep 21, 2024
6941c8e
Merge pull request #255 from Nexters/feature/#254-마이페이지-계정-관리-구현
leemhyungyu Sep 22, 2024
632ce68
[Feature/#251] 연락처 차단 기능 구현 (#256)
JongHoooon Sep 22, 2024
f456fb4
[Feature/#259] 마이페이지 1:1 문의 기능 구현 (#260)
leemhyungyu Sep 22, 2024
b6a4f16
feat: 이용약관, 개인정보처리 클릭 시 기능 구현 (#262)
leemhyungyu Sep 22, 2024
9548a32
[Feature/#257] 마이페이지 앱 버전 업데이트 기능 구현 (#258)
JongHoooon Sep 22, 2024
89ea3f5
[feature/#264] 마이페이지 프로필 수정 웹뷰 연결 (#270)
JongHoooon Sep 22, 2024
737a6da
[Feature/#263] 연락처 접근 권한 허용안함 시 설정 이동 (#265)
leemhyungyu Sep 22, 2024
d3c2872
[Feature/#266] 마이페이지 진입 시 연락처 차단 개수 동기화 (#267)
leemhyungyu Sep 22, 2024
97e6980
[Feature/#268] 연락처 차단 완료 시 Toast 띄우기 (#269)
leemhyungyu Sep 22, 2024
1524b1a
Release/1.0.8 -> develop (#285)
leemhyungyu Sep 26, 2024
fd7236c
setting: Create pull-request.yml
JongHoooon Oct 3, 2024
1f88d7c
Update pull-request.yml
JongHoooon Oct 3, 2024
85257cd
Update pull-request.yml
JongHoooon Oct 3, 2024
3bb4a4c
Update pull-request.yml
JongHoooon Oct 3, 2024
26ae24d
Update pull-request.yml
JongHoooon Oct 3, 2024
e280a64
[Setting/#303] assertion error 슬랙 로깅 연결 #304
JongHoooon Oct 15, 2024
ecd6d00
feat: 호감 탭 추가 및 호감 웹뷰 연결 (#307)
JongHoooon Oct 15, 2024
bffc701
[Fix/#308] onboarding 4 디자인 qa 반영 #309
JongHoooon Oct 15, 2024
74ca31a
[refactor/#310] 마이페이지 중복된 setTabBar 모디파이어 제거 #311
JongHoooon Oct 15, 2024
d4f760f
[Refactor/#296] 웹뷰 프로필 생성 변경된 URL 적용 #312
JongHoooon Oct 15, 2024
194ea25
[Feature/#306] 호감 tab 웹뷰 action 핸들링 #313
JongHoooon Oct 15, 2024
f72537b
[Fix/#314] 보틀 보관함 하단에 탭 높이만큼 패딩값 추가 필요 #315
JongHoooon Oct 15, 2024
cf3f08f
[Feature/#316] 추천 보틀 웹뷰 액션 핸들링 #317
JongHoooon Oct 15, 2024
6e3749b
[Refactor/#319] 프로필 이미지 블러 처리 로직 제거 #320
JongHoooon Oct 15, 2024
d2aa549
chore: 버전, 빌드 넘버 업데이트 v1.0.9(31) (#321)
leemhyungyu Oct 16, 2024
152573a
[Feature/#290] 문답화면 리스트 디자인시스템 구현 (#292)
leemhyungyu Oct 16, 2024
ba3706a
[Feature/#294] 문답화면 segmented control 디자인 수정 (#297)
leemhyungyu Oct 16, 2024
41e2298
[Feature/#324] 문답 화면 새로운 디자인 적용 (#325)
leemhyungyu Oct 16, 2024
1f78df6
[Feature/#323] 문답 화면 탭바 적용 (#326)
leemhyungyu Oct 16, 2024
0612812
[Feature/#331] 코치 마크 구현 (#338)
leemhyungyu Nov 4, 2024
2531eb0
chore: 연락처 접근 권한 요청 문구 수정
JongHoooon Nov 5, 2024
dbd1c0b
feat: 문답 이후 상태 업데이트
leemhyungyu Nov 6, 2024
1688aa9
[Feature/#335] 문답 화면 텍스트필드 버그 수정 (#336)
leemhyungyu Nov 7, 2024
59e6243
[Feature/#329] 사진 3개 등록 대응 (#337)
leemhyungyu Nov 7, 2024
1fb142e
[Feature/#343] 프로필 수정 완료 후 업데이트 처리 (#344)
leemhyungyu Nov 7, 2024
a062fdf
[Feature/#346] 웹뷰 safearea top ingore 처리 (#347)
leemhyungyu Nov 7, 2024
19eac8e
[Feature/#328] 자기 소개 웹뷰 연결 (#348)
leemhyungyu Nov 7, 2024
1146d85
[Feature/#349] 보틀 보관함 디자인 qa 반영 (#350)
leemhyungyu Nov 7, 2024
e294b2d
[Feature/#339] 앱 알림 설정 유무 등록 API 연결 #342
JongHoooon Nov 8, 2024
559f6c8
[Fix/#345] pingPongBottleList empty 인 경우 이미지 좌우 불필요한 패딩 수정 #351
JongHoooon Nov 8, 2024
c122bea
[Feature/#341] 통신 API 헤더에 부가 정보들 추가 #352
JongHoooon Nov 8, 2024
5f3d552
chore: 연락처 접근 권한 요청 문구 수정
JongHoooon Nov 5, 2024
032b7d9
feat: 문답 이후 상태 업데이트
leemhyungyu Nov 6, 2024
7c03dca
feat: 모래사장 화면 자기소개 작성 및 보틀 보여주기 로직 원복 (#354)
JongHoooon Nov 9, 2024
0f02a2d
[Feature/#355] 웹뷰에서 카메라 접근 시 핸들링 #356
JongHoooon Nov 9, 2024
fb8a51a
[Feature/#357] 로딩 인디케이터 변경된 디자인 반영 #358
JongHoooon Nov 9, 2024
f02f768
[Feature/#318] 도착한 보틀 리스트, 도착한 보틀 상세 화면 로딩 인디케이터 적용
JongHoooon Nov 9, 2024
640a23c
chore: 빌드 넘버 업데이트(36)
JongHoooon Nov 9, 2024
24b7771
chore: profile setup interface에 base webview interface 의존성 주입
JongHoooon Nov 9, 2024
49dc891
fix: 모래사장 바로가기 버튼 클릭 시 보틀 리스트로 넘어가지 않게 수정
JongHoooon Nov 9, 2024
0bd61c7
Merge branch 'release/1.0.10' of https://github.com/Nexters/Bottles_i…
leemhyungyu Nov 9, 2024
a8cf272
fix: feat: 모래사장 화면 자기소개 작성 및 보틀 보여주기 로직 수정
leemhyungyu Nov 9, 2024
9efce44
chore: 빌드 넘버 업데이트(37)
leemhyungyu Nov 9, 2024
a351a98
fix: 모래사장 바로가기 버튼 클릭 시 보틀 리스트로 넘어가게 수정
leemhyungyu Nov 9, 2024
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
58 changes: 58 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Bottles Pull Request Workflow

on:
pull_request:
branches:
- develop
types: [ opened, reopened, synchronize ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Send Slack Notification
if: github.event.action == 'opened' || github.event.action == 'reopened'
env:
DATA: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*iOS PR* :bell: <@U07LESGBQEP> <@U07LHEEU2BW>"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Author:*\n<https://github.com/${{ github.event.sender.login }}|${{ github.event.sender.login }}>"
},
{
"type": "mrkdwn",
"text": "*Title:*\n${{ github.event.pull_request.title }}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Description:*\n${{ github.event.pull_request.body }}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Pull Request URL:*\n<${{ github.event.pull_request.html_url }}|View PR>"
}
}
]
}
run: |
curl -X POST -H 'Content-type: application/json' \
-d "$DATA" \
${{ secrets.SLACK_WEBHOOK_URL }}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public extension ModulePath {
// MARK: - FeatureModule
public extension ModulePath {
enum Feature: String, CaseIterable {
case GoodFeeling
case Guide
case TabBar
case Report
Expand All @@ -48,6 +49,7 @@ public extension ModulePath {

public extension ModulePath {
enum Domain: String, CaseIterable {
case Application
case Error
case User
case Report
Expand All @@ -64,6 +66,7 @@ public extension ModulePath {

public extension ModulePath {
enum Core: String, CaseIterable {
case URLHandler
case Toast
case KeyChainStore
case WebView
Expand Down
42 changes: 40 additions & 2 deletions Projects/App/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ final class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
UIApplication.shared.registerForRemoteNotifications()
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self

setNotification()
application.registerForRemoteNotifications()

store.send(.appDelegate(.didFinishLunching))
return true
}
}

// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
func messaging(
_ messaging: Messaging,
Expand All @@ -62,3 +62,41 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
return [.badge, .sound, .banner, .list]
}
}

// MARK: - objc funcs
private extension AppDelegate {
@objc func checkPushNotificationStatus() {
UNUserNotificationCenter.current()
.getNotificationSettings { [weak self] permission in
guard let self = self else { return }
DispatchQueue.main.async {
switch permission.authorizationStatus {
case .notDetermined:
self.store.send(.appDelegate(.pushNotificationAllowStatusDidChanged(isAllow: true)))
case .denied:
self.store.send(.appDelegate(.pushNotificationAllowStatusDidChanged(isAllow: false)))
case .authorized:
self.store.send(.appDelegate(.pushNotificationAllowStatusDidChanged(isAllow: true)))
case .provisional:
self.store.send(.appDelegate(.pushNotificationAllowStatusDidChanged(isAllow: false)))
case .ephemeral:
self.store.send(.appDelegate(.pushNotificationAllowStatusDidChanged(isAllow: true)))
@unknown default:
Log.error("Unknow Notification Status")
}
}
}
}
}

// MARK: - Private Methods
private extension AppDelegate {
func setNotification() {
NotificationCenter.default.addObserver(
self,
selector: #selector(checkPushNotificationStatus),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
}
}
75 changes: 74 additions & 1 deletion Projects/Core/Logger/Interface/Sources/Log.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 임현규 on 7/23/24.
//

import Foundation
import UIKit
import OSLog

public enum Log {
Expand Down Expand Up @@ -132,6 +132,79 @@ public extension Log {
let logMessage = "\(message ?? "")"
log(message: logMessage, level: level, fileName: fileName, line: line, funcName: funcName)
assertionFailure(logMessage)
#if !DEBUG
Task {
guard let url = URL(string: Bundle.main.infoDictionary?["SLACK_WEBHOOK_URL"] as? String ?? "")
else {
return
}
guard let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
else {
return
}
async let device = UIDevice.current
let systemVersion = await device.systemVersion
let deviceName = await UIDevice.current.name

let errorLogJsonObject: [String: Any] = [
"pretext": "iOS Error Occured🔥",
"color": "#36a64f",
"fields": [
[
"title": "Message",
"value": "\(message ?? "no message")",
"short": true
],
[
"title": "File Name",
"value": "\(fileName)",
"short": true
],
[
"title": "Function Name",
"value": "\(funcName)",
"short": true
],
[
"title": "Line",
"value": "\(line)",
"short": true
],
[
"title": "Version",
"value": "\(appVersion)",
"short": true
],
[
"title": "Build Number",
"value": "\(buildNumber)",
"short": true
],
[
"title": "Device Name",
"value": "\(deviceName)",
"short": true
],
[
"title": "iOS Version",
"value": "\(systemVersion)",
"short": true
]
]
]
do {
let errorLogJsonData = try JSONSerialization.data(withJSONObject: errorLogJsonObject)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = errorLogJsonData
_ = try await URLSession.shared.data(for: request)
} catch {
Log.debug(error)
}
}
#endif
}

static func fatal(message: Any?, level: Level = .fault, fileName: String = #fileID, line: Int = #line, funcName: StaticString = #function) {
Expand Down
3 changes: 2 additions & 1 deletion Projects/Core/Network/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ let project = Project.makeModule(
factory: .init(
dependencies: [
.core(interface: .Network),
.core(interface: .Logger)
.core(interface: .Logger),
.core(implements: .KeyChainStore)
]
)
),
Expand Down
26 changes: 26 additions & 0 deletions Projects/Core/Network/Sources/Interceptor/TokenInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import Foundation
import UIKit

import CoreKeyChainStore
import CoreLoggerInterface
Expand All @@ -30,7 +31,32 @@ public class TokenInterceptor: RequestInterceptor {
urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
}

var deviceName: String {
if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
return simulatorModelIdentifier
} else {
var systemInfo = utsname()
uname(&systemInfo)
let modelIdentifier = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) { ptr in
String(validatingUTF8: ptr)
}
}
return modelIdentifier ?? ""
}
}
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? ""
let deviceID = UIDevice.current.identifierForVendor?.uuidString ?? ""
var osVersion = UIDevice.current.systemVersion

urlRequest.setValue(appVersion, forHTTPHeaderField: "X-App-Version")
urlRequest.setValue(deviceName, forHTTPHeaderField: "X-Device-Model")
urlRequest.setValue(osVersion, forHTTPHeaderField: "X-OS-Version")
urlRequest.setValue(deviceID, forHTTPHeaderField: "X-Device-ID")
urlRequest.setValue("iOS", forHTTPHeaderField: "X-App-Platform")

print(urlRequest.headers)

completion(.success(urlRequest))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class MoyaLoggerPlugin: PluginType {
log += "header: \(headers)\n"
}
if let body = httpRequest.httpBody, let bodyString = String(bytes: body, encoding: String.Encoding.utf8) {
log += "bodyString: \(bodyString)"
log += "bodyString: \(bodyString)\n"
}

log += "---------------------------------------------"
Expand Down Expand Up @@ -79,7 +79,7 @@ final class MoyaLoggerPlugin: PluginType {
if let data = error.response?.data {
log += "Data - \(data)\n"
} else {
log += "Data - empty"
log += "Data - empty\n"
}

log += "---------------------------------------------"
Expand Down
31 changes: 31 additions & 0 deletions Projects/Core/URLHandler/Interface/Sources/BottleURLType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// BottleURLType.swift
// CoreURLHandlerInterface
//
// Created by JongHoon on 9/20/24.
//

import Foundation

public enum BottleURLType {
case bottleAppStore
case bottleAppLookUp
case kakaoChannelTalk
case setting

public var url: URL {
switch self {
case .bottleAppStore:
return URL(string: Bundle.main.infoDictionary?["APP_STORE_URL"] as? String ?? "")!

case .kakaoChannelTalk:
return URL(string: Bundle.main.infoDictionary?["KAKAO_CHANNEL_TALK_URL"] as? String ?? "")!

case .bottleAppLookUp:
return URL(string: Bundle.main.infoDictionary?["APP_LOOK_UP_URL"] as? String ?? "")!

case .setting:
return URL(string: "App-prefs:root=General")!
}
}
}
19 changes: 19 additions & 0 deletions Projects/Core/URLHandler/Interface/Sources/URLHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// URLHandler.swift
// CoreURLHandlerInterface
//
// Created by JongHoon on 9/20/24.
//

import UIKit

public final class URLHandler {

public static let shared = URLHandler()

private init() { }

public func openURL(urlType: BottleURLType) {
UIApplication.shared.open(urlType.url)
}
}
40 changes: 40 additions & 0 deletions Projects/Core/URLHandler/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ProjectDescription
import ProjectDescriptionHelpers
import DependencyPlugin

let project = Project.makeModule(
name: ModulePath.Core.name+ModulePath.Core.URLHandler.rawValue,
targets: [
.core(
interface: .URLHandler,
factory: .init()
),
.core(
implements: .URLHandler,
factory: .init(
dependencies: [
.core(interface: .URLHandler)
]
)
),

.core(
testing: .URLHandler,
factory: .init(
dependencies: [
.core(interface: .URLHandler)
]
)
),
.core(
tests: .URLHandler,
factory: .init(
dependencies: [
.core(testing: .URLHandler),
.core(implements: .URLHandler)
]
)
),

]
)
1 change: 1 addition & 0 deletions Projects/Core/URLHandler/Sources/Source.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// This is for Tuist
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// This is for Tuist
Loading