Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MOB-2012] BezierEmoji 구현 #78

Open
wants to merge 4 commits into
base: feature/redesign_bezier
Choose a base branch
from
Open
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
107 changes: 107 additions & 0 deletions BezierSwift/Sources/Components/Emoji/BezierEmoji.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// BezierEmoji.swift
//
//
// Created by Tom on 9/19/24.
//

import SwiftUI

import SDWebImageSwiftUI

private enum Metric {
static let bottomTrailingPadding: CGFloat = -4
}

private enum Constant {
static let emojiUrlString: String = "https://cf.channel.io/asset/emoji/images/80/%@.png"
}
// - MARK: BezierAvatar
public struct BezierEmoji: View {
// MARK: Size
public enum Size {
case pt16
case pt20
case pt24
case pt30
case pt36
case pt42
case pt48
case pt60
case pt72
case pt90
case pt120
}

// MARK: Badge
public enum Badge {
case chat
}

// MARK: Properties
private let name: String
private let size: Size
private let badge: Badge?

private var emojiUrl: URL? {
if let encodedEmojiUrlString = String(format: Constant.emojiUrlString, self.name).percentEncode() {
return URL(string: encodedEmojiUrlString)
} else {
return nil
}
}

// MARK: Initializer
/// - Parameters:
/// - name: ch-asset 기반으로 emoji 의 file name 을 사용합니다.
/// - emojipedia 를 통해 name을 검색 할 수 있으며, Shortcodes/github 기준으로 사용합니다.
/// - ex) https://emojipedia.org/😄#technical
Copy link
Contributor Author

Choose a reason for hiding this comment

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

emoji 전체를 열거형으로 리스트업 하는 것보다 스트링을 통해서 가져오도록 논의가 되었습니다.

/// - size: emoji 사이즈는 `16pt`, `20pt`, `24pt`, `30pt`, `36pt`, `42pt`, `48pt`, `60pt`, `72pt`, `90pt`, `120pt` 로 총 11개 사이즈를 가집니다.
/// - emoji의 경우 예외적으로 semantic name 이 아닌, raw 한 수치 그대로 사용합니다.
/// - badge: 이모지의 상태 배지가 포함될 수 있습니다.
/// - chat (public / private)
public init(name: String, size: Size, badge: Badge? = nil) {
self.name = name
self.size = size
self.badge = badge
}

// MARK: Body
public var body: some View {
WebImage(url: self.emojiUrl)
.resizable()
.scaledToFit()
.frame(length: self.length)
.if(self.badge.isNotNil) { view in
view
.overlay(
BezierChatBadge(size: .medium)
.padding([.bottom, .trailing], Metric.bottomTrailingPadding),
alignment: .bottomTrailing
)
}
}
}

// - MARK: Style
extension BezierEmoji {
private var length: CGFloat {
switch self.size {
case .pt16: return 16
case .pt20: return 20
case .pt24: return 24
case .pt30: return 30
case .pt36: return 36
case .pt42: return 42
case .pt48: return 48
case .pt60: return 60
case .pt72: return 72
case .pt90: return 90
case .pt120: return 120
}
}
}

#Preview {
BezierEmoji(name: "+1", size: .pt24, badge: .chat)
}
26 changes: 26 additions & 0 deletions BezierSwift/Sources/Extensions/OptionalExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// File.swift
//
//
// Created by Tom on 9/19/24.
//

import Foundation

extension Optional {
var isNil: Bool { self == nil }
var isNotNil: Bool { self != nil }
}

extension Optional where Wrapped == Bool {
var beTrue: Bool { self == true }
var beFalse: Bool { self == false }
}

extension Optional where Wrapped == String {
public var isNilOrEmpty: Bool {
guard let self else { return true }

return self.isEmpty
}
}
7 changes: 7 additions & 0 deletions BezierSwift/Sources/Extensions/StringExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ extension String {

return (red: 1, green: 1, blue: 1, alpha: 1)
}

func percentEncode() -> String? {
let unreserved = ":-._~/?#"
let allowed = NSMutableCharacterSet.alphanumeric()
allowed.addCharacters(in: unreserved)
return self.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
E220176D2C75D67900578E64 /* BezierIconButtonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E220176C2C75D67900578E64 /* BezierIconButtonExample.swift */; };
E22017702C75E09900578E64 /* BezierFloatingButtonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E220176F2C75E09900578E64 /* BezierFloatingButtonExample.swift */; };
E22017722C75E0A400578E64 /* BezierFloatingIconButtonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22017712C75E0A400578E64 /* BezierFloatingIconButtonExample.swift */; };
E255DE992C9C824E00102219 /* BezierEmojiExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E255DE982C9C824E00102219 /* BezierEmojiExample.swift */; };
E258E6BE2C3D8D9C00F69680 /* BezierButtonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E258E6BD2C3D8D9C00F69680 /* BezierButtonExample.swift */; };
E28212322A4B32F700018327 /* SwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28212312A4B32F700018327 /* SwiftUIExampleApp.swift */; };
E28212342A4B32F700018327 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28212332A4B32F700018327 /* ContentView.swift */; };
Expand All @@ -27,6 +28,7 @@
E220176C2C75D67900578E64 /* BezierIconButtonExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierIconButtonExample.swift; sourceTree = "<group>"; };
E220176F2C75E09900578E64 /* BezierFloatingButtonExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierFloatingButtonExample.swift; sourceTree = "<group>"; };
E22017712C75E0A400578E64 /* BezierFloatingIconButtonExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierFloatingIconButtonExample.swift; sourceTree = "<group>"; };
E255DE982C9C824E00102219 /* BezierEmojiExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierEmojiExample.swift; sourceTree = "<group>"; };
E258E6BD2C3D8D9C00F69680 /* BezierButtonExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierButtonExample.swift; sourceTree = "<group>"; };
E282122E2A4B32F700018327 /* SwiftUIExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
E28212312A4B32F700018327 /* SwiftUIExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExampleApp.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -70,6 +72,7 @@
E2EF05FB2C5A4CDC00C57676 /* BezierLoaderExample.swift */,
E2A392B62C958A540015FA6F /* BezierAvatarExample.swift */,
E2A392B82C98169D0015FA6F /* BezierAvatarGroupExample.swift */,
E255DE982C9C824E00102219 /* BezierEmojiExample.swift */,
);
path = Examples;
sourceTree = "<group>";
Expand Down Expand Up @@ -197,6 +200,7 @@
E2EF05FC2C5A4CDC00C57676 /* BezierLoaderExample.swift in Sources */,
E2A392B92C98169D0015FA6F /* BezierAvatarGroupExample.swift in Sources */,
E22017722C75E0A400578E64 /* BezierFloatingIconButtonExample.swift in Sources */,
E255DE992C9C824E00102219 /* BezierEmojiExample.swift in Sources */,
E28D19602C365557009B34A2 /* AppDelegate.swift in Sources */,
E28212342A4B32F700018327 /* ContentView.swift in Sources */,
E28212322A4B32F700018327 /* SwiftUIExampleApp.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions Examples/SwiftUIExample/SwiftUIExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ struct ContentView: View {
} label: {
Text("Loader")
}
NavigationLink {
BezierEmojiExample()
} label: {
Text("Emoji")
}
} header: {
Text("Status")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// BezierEmojiExample.swift
// SwiftUIExample
//
// Created by Tom on 9/20/24.
//

import SwiftUI

import BezierSwift

struct BezierEmojiExample: View {
var body: some View {
BezierEmoji(
name: "+1",
size: .pt24,
badge: .chat
)
}
}

#Preview {
BezierEmojiExample()
}