Skip to content

Commit

Permalink
[2.0.0] 학과 검색 로직 추가 및 공유하기 버그 수정 (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
lgvv authored Mar 29, 2024
1 parent 3f93162 commit 2dd7f44
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ import ComposableArchitecture
public struct DepartmentEditorFeature {
@ObservableState
public struct State: Equatable {
/// 내가 선택한 학과
public var myDepartments: IdentifiedArrayOf<NoticeProvider>
public var results: IdentifiedArrayOf<NoticeProvider>

/// 모든학과
public var allDepartments: IdentifiedArrayOf<NoticeProvider>
/// 검색결과
public var searchResults: IdentifiedArrayOf<NoticeProvider>

public var searchText: String
public var focus: Field?

Expand Down Expand Up @@ -47,7 +51,8 @@ public struct DepartmentEditorFeature {
@Dependency(\.departments) var departments

self.myDepartments = IdentifiedArrayOf(uniqueElements: departments.getAll())
self.results = results
self.searchResults = []
self.allDepartments = results
self.searchText = searchText
self.focus = focus
self.displayOption = displayOption
Expand All @@ -68,6 +73,9 @@ public struct DepartmentEditorFeature {
case deleteAllMyDepartmentButtonTapped
/// 텍스트 필드의 xmark를 눌렀을 때
case clearTextFieldButtonTapped

/// 검색 문자열 변경
case searchQueryChanged(String)

/// 알림 관련 액션
case alert(PresentationAction<Alert>)
Expand All @@ -91,6 +99,8 @@ public struct DepartmentEditorFeature {

@Dependency(\.departments) var departments

private var engine: DepartmentSearchEngine = DepartmentSearchEngineImpl()

public var body: some ReducerOf<Self> {
BindingReducer()

Expand All @@ -100,7 +110,7 @@ public struct DepartmentEditorFeature {
return .none

case let .addDepartmentButtonTapped(id: id):
guard let department = state.results.first(where: { $0.id == id }) else {
guard let department = state.searchResults.first(where: { $0.id == id }) else {
return .none
}
guard !state.myDepartments.contains(department) else {
Expand Down Expand Up @@ -175,6 +185,17 @@ public struct DepartmentEditorFeature {
}
NoticeProvider.addedDepartments = state.myDepartments.elements
return .none

case let .searchQueryChanged(query):
state.searchText = query

if !state.searchText.isEmpty {
state.searchResults = engine.search(
keyword: query,
allDepartments: state.allDepartments
)
}
return .none

case .alert(.dismiss):
return .none
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Copyright (c) 2024 쿠링
// See the 'License.txt' file for licensing information.
//

import Models
import ComposableArchitecture

protocol DepartmentSearchEngine {
func search(keyword: String, allDepartments: IdentifiedArrayOf<NoticeProvider>) -> IdentifiedArrayOf<NoticeProvider>
}

struct DepartmentSearchEngineImpl: DepartmentSearchEngine {
/// 한글
private var hangeul = ["","","","","","","","","","","","","","","","","","",""]


/// 전체학과 정보와 주어진 검색 키워드를 기반으로 검색된 학과 리스트를 반환
///
///
/// - Parameters:
/// - keyword: 검색 키워드
/// - allDepartments: 모든 학과 리스트
func search(keyword: String, allDepartments: IdentifiedArrayOf<NoticeProvider>) -> IdentifiedArrayOf<NoticeProvider> {
var filteredDepartments: IdentifiedArrayOf<NoticeProvider>

if isChosung(keyword) {
let results = allDepartments.filter { department in
department.korName.contains(keyword) || searchChosung(department.korName).contains(keyword)
}

filteredDepartments = results
} else {
var correctResults = allDepartments
.filter { $0.korName.contains(keyword) }
.compactMap { $0 }
.sorted { $0.korName < $1.korName }

allDepartments.forEach { department in
var count = 0
var textChecker = Array(repeating: 0, count: keyword.count)
for alpha in department.korName {
for (idx, value) in keyword.enumerated() {
if value == alpha && textChecker[idx] == 0 {
textChecker[idx] = 1
count += 1
break
}
}

}
if count == keyword.count && !correctResults.contains(department) {
correctResults.append(department)
}
}
filteredDepartments = IdentifiedArray(correctResults)
}

return filteredDepartments
}

/// 해당 keyword가 초성문자인지 검사
private func isChosung(_ keyword: String) -> Bool {
var result = false

for char in keyword {
if 0 < hangeul.filter({ $0.contains(char) }).count {
result = true
} else {
result = false
break
}
}

return result
}

/// 초성 검색
private func searchChosung(_ keyword: String) -> String {
var result = ""

for char in keyword {
// unicodeScalars: 유니코드 스칼라 값의 모음으로 표현되는 문자열 값
let octal = char.unicodeScalars[char.unicodeScalars.startIndex].value

// ~=: 왼쪽에서 정의한 범위 값 안에 오른쪽의 값이 속하면 true, 아니면 false 반환
if 44032...55203 ~= octal {
let index = (octal - 0xac00) / 28 / 21
result = result + hangeul[Int(index)]
}
}
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public struct NoticeDetailFeature {
public struct State: Equatable {
public var notice: Notice
public var isBookmarked: Bool = false
public var shareItem: ActivityItem? = nil

public init(notice: Notice, isBookmarked: Bool? = nil) {
@Dependency(\.bookmarks) var bookmarks
Expand All @@ -34,7 +33,6 @@ public struct NoticeDetailFeature {

public enum Action: BindableAction, Equatable {
case bookmarkButtonTapped
case shareButtonTapped

case binding(BindingAction<State>)

Expand All @@ -55,12 +53,6 @@ public struct NoticeDetailFeature {
state.isBookmarked.toggle()
return .none

case .shareButtonTapped:
state.shareItem = ActivityItem(
items: state.notice.url
)
return .none

case .delegate:
return .none
}
Expand Down
14 changes: 8 additions & 6 deletions package-kuring/Sources/UIKit/DepartmentUI/DepartmentEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ public struct DepartmentEditor: View {
.frame(width: 16, height: 16)
.foregroundStyle(Color.Kuring.gray400)

TextField("추가할 학과를 검색해 주세요", text: $store.searchText)
.focused($focus, equals: .search)
.autocorrectionDisabled()
.bind($store.focus, to: self.$focus)
TextField(
"추가할 학과를 검색해 주세요",
text: $store.searchText.sending(\.searchQueryChanged)
)
.focused($focus, equals: .search)
.autocorrectionDisabled()
.bind($store.focus, to: self.$focus)

if !store.searchText.isEmpty {
Image(systemName: "xmark")
Expand Down Expand Up @@ -69,7 +72,7 @@ public struct DepartmentEditor: View {
} else {
// 검색결과
ScrollView {
ForEach(store.results) { result in
ForEach(store.searchResults) { result in
DepartmentRow(
department: result,
style: .radio(store.myDepartments.contains(result))
Expand Down Expand Up @@ -129,6 +132,5 @@ public struct DepartmentEditor: View {
reducer: { DepartmentEditorFeature() }
)
)
.navigationTitle("Department Editor")
}
}
1 change: 0 additions & 1 deletion package-kuring/Sources/UIKit/NoticeUI/NoticeApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ public struct NoticeApp: View {
case .departmentEditor:
if let store = store.scope(state: \.departmentEditor, action: \.departmentEditor) {
DepartmentEditor(store: store)
.navigationTitle("Department Editor")
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions package-kuring/Sources/UIKit/NoticeUI/NoticeDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public struct NoticeDetailView: View {

public var body: some View {
WebView(urlString: store.notice.url)
.activitySheet($store.shareItem)
.background(Color.Kuring.bg)
.toolbar {
ToolbarItem(placement: .principal) {
Expand All @@ -35,9 +34,9 @@ public struct NoticeDetailView: View {
)
}

Button {
self.store.send(.shareButtonTapped)
} label: {
ShareLink(
item: store.notice.url
) {
Image(systemName: "square.and.arrow.up")
}
}
Expand Down
2 changes: 1 addition & 1 deletion package-kuring/Sources/UIKit/SearchUI/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public struct SearchView: View {
.frame(width: 16, height: 16)
.foregroundStyle(Color.Kuring.gray300)

TextField("검색어를 입력해주세요", text: $store.searchInfo.text)
TextField("공지 제목 또는 교수명을 입력해주세요.", text: $store.searchInfo.text)
.focused($focus, equals: .search)
.autocorrectionDisabled()
.onSubmit { store.send(.search) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public struct SubscriptionApp: View {
action: \.departmentEditor
) {
DepartmentEditor(store: store)
.navigationTitle("Department Editor")
}
}
}
Expand Down

0 comments on commit 2dd7f44

Please sign in to comment.