Skip to content

Commit

Permalink
Merge pull request #235 from tatsuz0u/develop
Browse files Browse the repository at this point in the history
Features & Bugfixes
  • Loading branch information
tatsuz0u authored Feb 23, 2022
2 parents 931eeb2 + ed73249 commit e156f7c
Show file tree
Hide file tree
Showing 61 changed files with 1,397 additions and 1,203 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
types: [closed]
env:
DEVELOPER_DIR: /Applications/Xcode_13.2.1.app
APP_VERSION: '2.2.2'
APP_VERSION: '2.3.0'
SCHEME_NAME: 'EhPanda'
ALTSTORE_JSON_PATH: './AltStore.json'
BUILDS_PATH: '/tmp/action-builds'
Expand Down
63 changes: 56 additions & 7 deletions EhPanda.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@
"version": "0.3.2"
}
},
{
"package": "SwiftCommonMark",
"repositoryURL": "https://github.com/gonzalezreal/SwiftCommonMark.git",
"state": {
"branch": null,
"revision": "ed252beaddecce28ea6363f800c773d6169011b8",
"version": "1.0.0"
}
},
{
"package": "swiftui-navigation",
"repositoryURL": "https://github.com/pointfreeco/swiftui-navigation.git",
Expand Down
2 changes: 2 additions & 0 deletions EhPanda/App/Constant.strings
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"ehpanda.acknowledgements.link.SFSafeSymbols" = "https://github.com/SFSafeSymbols/SFSafeSymbols";
"ehpanda.acknowledgements.link.TTProgressHUD" = "https://github.com/honkmaster/TTProgressHUD";
"ehpanda.acknowledgements.link.swiftUINavigation" = "https://github.com/pointfreeco/swiftui-navigation";
"ehpanda.acknowledgements.link.swiftCommonMark" = "https://github.com/gonzalezreal/SwiftCommonMark";
"ehpanda.acknowledgements.link.ehTagTranslationDatabase" = "https://github.com/EhTagTranslation/Database";
"ehpanda.acknowledgements.link.TCA" = "https://github.com/pointfreeco/swift-composable-architecture";

Expand All @@ -88,5 +89,6 @@
"ehpanda.acknowledgements.text.SFSafeSymbols" = "SFSafeSymbols";
"ehpanda.acknowledgements.text.TTProgressHUD" = "TTProgressHUD";
"ehpanda.acknowledgements.text.swiftUINavigation" = "SwiftUI Navigation";
"ehpanda.acknowledgements.text.swiftCommonMark" = "SwiftCommonMark";
"ehpanda.acknowledgements.text.ehTagTranslationDatabase" = "EhTagTranslation/Database";
"ehpanda.acknowledgements.text.TCA" = "The Composable Architecture";
7 changes: 4 additions & 3 deletions EhPanda/App/Tools/Clients/FileClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,18 @@ extension FileClient {
Future { promise in
DispatchQueue.global(qos: .userInitiated).async {
guard let data = try? Data(contentsOf: url),
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
let translations = try? JSONDecoder().decode(
EhTagTranslationDatabaseResponse.self, from: data
).tagTranslations
else {
promise(.failure(.parseFailed))
return
}
let translations = Parser.parseTranslations(dict: dict)
guard !translations.isEmpty else {
promise(.failure(.parseFailed))
return
}
promise(.success(.init(hasCustomTranslations: true, contents: translations)))
promise(.success(.init(hasCustomTranslations: true, translations: translations)))
}
}
.eraseToAnyPublisher()
Expand Down
3 changes: 3 additions & 0 deletions EhPanda/App/Tools/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ struct Defaults {
static let logs = "logs"
static let ehpandaLog = "EhPanda.log"
}
struct Regex {
static let tagSuggestion: NSRegularExpression? = try? .init(pattern: "(\\S+:\".+?\"|\".+?\"|\\S+:\\S+|\\S+)")
}
struct URL {
static var host: Foundation.URL { AppUtil.galleryHost == .exhentai ? exhentai : ehentai }
static let ehentai: Foundation.URL = .init(string: "https://e-hentai.org/").forceUnwrapped
Expand Down
15 changes: 15 additions & 0 deletions EhPanda/App/Tools/Extensions/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ extension String {
var localizedKey: LocalizedStringKey {
.init(self)
}
var linkStyled: String {
"[\(self)](\(Defaults.URL.ehentai.absoluteString))"
}
var stringsBesideColon: (String?, String) {
let strings = split(separator: ":").map(String.init)
if strings.count == 2, strings[0].notEmpty {
return (strings[0], strings[1])
}
return (nil, self)
}
var emojisRipped: String {
unicodeScalars
.filter { !$0.properties.isEmojiPresentation }
.reduce("") { $0 + .init($1) }
}

var urlEncoded: String {
addingPercentEncoding(
Expand Down
84 changes: 15 additions & 69 deletions EhPanda/App/Tools/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,22 @@ struct Parser {
let hex = style[rangeA.upperBound..<rangeB.lowerBound]
contentBackgroundColor = .init(hex: .init(hex))
}
if let index = tags.firstIndex(where: { $0.namespace == namespace }) {
if let index = tags.firstIndex(where: { $0.rawNamespace == namespace }) {
let contents = tags[index].contents
let galleryTagContent = GalleryTag.Content(
text: contentText, displayText: contentText,
isVotedUp: false, isVotedDown: false,
backgroundColor: contentBackgroundColor
)
let newContents = contents + [galleryTagContent]
tags[index] = .init(namespace: namespace, contents: newContents)
tags[index] = .init(rawNamespace: namespace, contents: newContents)
} else {
let galleryTagContent = GalleryTag.Content(
text: contentText, displayText: contentText,
isVotedUp: false, isVotedDown: false,
backgroundColor: contentBackgroundColor
)
tags.append(.init(namespace: namespace, contents: [galleryTagContent]))
tags.append(.init(rawNamespace: namespace, contents: [galleryTagContent]))
}
}
return tags
Expand Down Expand Up @@ -326,15 +328,22 @@ struct Parser {
let namespace = String(tcText.dropLast())
var contents = [GalleryTag.Content]()
for divLink in link.xpath("//div") {
guard var text = divLink.text else { continue }
guard var text = divLink.text, let aClass = divLink.at_xpath("//a")?.className else { continue }
let displayText = text
if let range = text.range(of: " | ") {
text = .init(text[..<range.lowerBound])
}
contents.append(.init(text: text, displayText: displayText, backgroundColor: nil))
contents.append(
.init(
text: text, displayText: displayText,
isVotedUp: aClass == "tup",
isVotedDown: aClass == "tdn",
backgroundColor: nil
)
)
}

tags.append(.init(namespace: namespace, contents: contents))
tags.append(.init(rawNamespace: namespace, contents: contents))
}

return tags
Expand Down Expand Up @@ -1726,67 +1735,4 @@ extension Parser {
return .unrecognized(content: expireDescription)
}
}

// MARK: Translation
static func parseTranslations(dict: [String: Any], language: TranslatableLanguage? = nil) -> [String: String] {
func parseCHSTranslations(dict: [String: Any]) -> [String: String] {
let categories = dict["data"] as? [[String: Any]] ?? []
let translationsBeforeMapping = categories.compactMap {
$0["data"] as? [String: Any]
}.reduce([], +)

var translations = [String: String]()
translationsBeforeMapping.forEach { translation in
let originalText = translation.key
let dict = translation.value as? [String: Any]

if let translatedText = dict?["name"] as? String {
translations[originalText] = translatedText
}
}
return translations
}
func convertToCHT(dict: [String: String]) -> [String: String] {
func customConversion(dict: inout [String: String]) {
if dict["full color"] != nil {
dict["full color"] = "全彩"
}
}
guard let preferredLanguage = Locale.preferredLanguages.first else { return [:] }

var translations = [String: String]()

var options: ChineseConverter.Options = [.traditionalize]
if preferredLanguage.contains("HK") {
options = [.traditionalize, .hkStandard]
} else if preferredLanguage.contains("TW") {
options = [.traditionalize, .twStandard, .twIdiom]
}

guard let converter = try? ChineseConverter(options: options)
else { return [:] }

dict.forEach { key, value in
translations[key] = converter.convert(value)
}
customConversion(dict: &translations)

return translations
}
func tryParseAnyTranslations(dict: [String: Any]) -> [String: String] {
dict as? [String: String] ?? [:]
}

let chsTranslations = parseCHSTranslations(dict: dict)
switch language {
case .japanese:
return tryParseAnyTranslations(dict: dict)
case .simplifiedChinese:
return chsTranslations
case .traditionalChinese:
return convertToCHT(dict: chsTranslations)
default:
return chsTranslations.isEmpty ? tryParseAnyTranslations(dict: dict) : chsTranslations
}
}
}
43 changes: 43 additions & 0 deletions EhPanda/App/Tools/Utilities/MarkdownUtil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// MarkdownUtil.swift
// EhPanda
//
// Created by 荒木辰造 on R 4/02/20.
//

import CasePaths
import CommonMark
import Foundation

struct MarkdownUtil {
static func parseTexts(markdown: String) -> [String] {
(try? Document(markdown: markdown))?.blocks
.compactMap((/Block.paragraph).extract)
.flatMap(\.text)
.compactMap((/Inline.text))
?? []
}
static func parseLinks(markdown: String) -> [URL] {
(try? Document(markdown: markdown))?.blocks
.compactMap((/Block.paragraph).extract)
.flatMap(\.text)
.compactMap((/Inline.link))
.compactMap(\.url)
?? []
}
static func parseImages(markdown: String) -> [URL] {
(try? Document(markdown: markdown))?.blocks
.compactMap((/Block.paragraph).extract)
.flatMap(\.text)
.compactMap((/Inline.image))
.compactMap { image in
if image.url?.absoluteString.isValidURL == true {
return image.url
} else if let title = image.title, title.isValidURL {
return .init(string: title)
}
return nil
}
?? []
}
}
37 changes: 24 additions & 13 deletions EhPanda/App/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@
"general.setting.view.title.general" = "Allgemein";
"general.setting.view.title.language" = "Sprache";
"general.setting.view.title.autoLock" = "Auto-Lock";
"general.setting.view.title.enablesTagsExtension" = "Enables tags extension";
"general.setting.view.title.translatesTags" = "Translates tags";
"general.setting.view.title.showsTagsSearchSuggestions" = "Shows tags search suggestions";
"general.setting.view.title.showsImagesInTags" = "Shows images in tags";
"general.setting.view.title.redirectsLinksToTheSelectedHost" = "Links zum ausgewählten Host umleiten";
"general.setting.view.title.detectsLinksFromClipboard" = "Übernimmt automatisch Links aus der Zwischenablage";
"general.setting.view.title.backgroundBlurRadius" = "Background blur radius";
Expand All @@ -192,7 +195,7 @@
"general.setting.view.button.removeCustomTranslations" = "Remove custom translations";
"general.setting.view.button.clearImageCaches" = "Zwischengespeicherte Bilder (Cache) löschen";
"general.setting.view.value.defaultLanguageDescription" = "N/A";
"general.setting.view.section.title.tagsTranslation" = "Tags translation";
"general.setting.view.section.title.tags" = "Tags";
"general.setting.view.section.title.navigation" = "Navigation";
"general.setting.view.section.title.security" = "Sicherheit";
"general.setting.view.section.title.caches" = "Caches";
Expand Down Expand Up @@ -263,6 +266,10 @@
"detail.view.toolbar.item.button.archives" = "Archiv";
"detail.view.toolbar.item.button.torrents" = "Torrents";
"detail.view.toolbar.item.button.share" = "Teilen";
"detail.view.context.menu.button.detail" = "Detail";
"detail.view.context.menu.button.withdrawVote" = "Withdraw vote";
"detail.view.context.menu.button.voteUp" = "Vote up";
"detail.view.context.menu.button.voteDown" = "Vote down";
"detail.view.scroll.section.title.favorited" = "Favorisiert";
"detail.view.scroll.section.title.language" = "Sprache";
"detail.view.scroll.section.title.ratings" = "%@ Bewertungen";
Expand Down Expand Up @@ -318,6 +325,10 @@
"gallery.visibility.value.no" = "No (%@)";
"gallery.visibility.value.no.reason.expunged" = "Expunged";

// MARK: TagDetailView
"tag.detail.view.section.title.images" = "Images";
"tag.detail.view.section.title.links" = "Links";

// MARK: CommentsView
"comments.view.title.comments" = "Kommentar";

Expand Down Expand Up @@ -546,18 +557,18 @@
"enum.category.value.private" = "Private";

// MARK: TagCategory
"enum.tag.category.value.reclass" = "Reclass";
"enum.tag.category.value.language" = "Sprache";
"enum.tag.category.value.parody" = "Parodie";
"enum.tag.category.value.character" = "Charakter";
"enum.tag.category.value.group" = "Gruppe";
"enum.tag.category.value.artist" = "Künstler";
"enum.tag.category.value.male" = "Männlich";
"enum.tag.category.value.female" = "Weiblich";
"enum.tag.category.value.mixed" = "Mixed";
"enum.tag.category.value.cosplayer" = "Cosplayer";
"enum.tag.category.value.other" = "Other";
"enum.tag.category.value.temp" = "Temp";
"enum.tag.namespace.value.reclass" = "Reclass";
"enum.tag.namespace.value.language" = "Sprache";
"enum.tag.namespace.value.parody" = "Parodie";
"enum.tag.namespace.value.character" = "Charakter";
"enum.tag.namespace.value.group" = "Gruppe";
"enum.tag.namespace.value.artist" = "Künstler";
"enum.tag.namespace.value.male" = "Männlich";
"enum.tag.namespace.value.female" = "Weiblich";
"enum.tag.namespace.value.mixed" = "Mixed";
"enum.tag.namespace.value.cosplayer" = "Cosplayer";
"enum.tag.namespace.value.other" = "Other";
"enum.tag.namespace.value.temp" = "Temp";

// MARK: Language
"enum.language.value.invalid" = "./.";
Expand Down
Loading

0 comments on commit e156f7c

Please sign in to comment.