Compare commits

...

9 Commits

Author SHA1 Message Date
Arkadiusz Fal
1b090fcd51 Bump build number 2021-12-06 19:15:05 +01:00
Arkadiusz Fal
12eb4401b5 Update README 2021-12-06 19:13:57 +01:00
Arkadiusz Fal
170f2ee94e Fix reloading favorites view 2021-12-06 19:13:49 +01:00
Arkadiusz Fal
fe56739211 Fix crash on dismissing channel playlist on iOS 2021-12-06 19:13:37 +01:00
Arkadiusz Fal
759a942426 Fix search field on macOS 2021-12-06 19:13:20 +01:00
Arkadiusz Fal
8d9bbf647a Fix disabling comments on tvOS 2021-12-06 19:12:59 +01:00
Arkadiusz Fal
eeb7b1f151 Improve search suggestions 2021-12-06 19:12:33 +01:00
Arkadiusz Fal
62bff9283c Faster replacing player item 2021-12-06 19:12:02 +01:00
Arkadiusz Fal
3624c9619a Add setting for displaying comments in separate tab or below description 2021-12-06 19:11:19 +01:00
13 changed files with 165 additions and 178 deletions

View File

@@ -29,6 +29,12 @@ final class CommentsModel: ObservableObject {
!Defaults[.commentsInstanceID].isNil && !Defaults[.commentsInstanceID]!.isEmpty !Defaults[.commentsInstanceID].isNil && !Defaults[.commentsInstanceID]!.isEmpty
} }
#if !os(tvOS)
static var placement: CommentsPlacement {
Defaults[.commentsPlacement]
}
#endif
var nextPageAvailable: Bool { var nextPageAvailable: Bool {
!(nextPage?.isEmpty ?? true) !(nextPage?.isEmpty ?? true)
} }

View File

@@ -29,6 +29,7 @@ extension PlayerModel {
} }
func playNow(_ video: Video, at time: TimeInterval? = nil) { func playNow(_ video: Video, at time: TimeInterval? = nil) {
player.replaceCurrentItem(with: nil)
addCurrentItemToHistory() addCurrentItemToHistory()
enqueueVideo(video, prepending: true) { _, item in enqueueVideo(video, prepending: true) { _, item in
@@ -92,6 +93,7 @@ extension PlayerModel {
} }
func advanceToItem(_ newItem: PlayerQueueItem, at time: TimeInterval? = nil) { func advanceToItem(_ newItem: PlayerQueueItem, at time: TimeInterval? = nil) {
player.replaceCurrentItem(with: nil)
addCurrentItemToHistory() addCurrentItemToHistory()
remove(newItem) remove(newItem)

View File

@@ -9,6 +9,7 @@ final class SearchModel: ObservableObject {
@Published var query = SearchQuery() @Published var query = SearchQuery()
@Published var queryText = "" @Published var queryText = ""
@Published var querySuggestions = Store<[String]>() @Published var querySuggestions = Store<[String]>()
@Published var suggestionsText = ""
@Published var fieldIsFocused = false @Published var fieldIsFocused = false
@@ -88,7 +89,7 @@ final class SearchModel: ObservableObject {
suggestionsDebounceTimer?.invalidate() suggestionsDebounceTimer?.invalidate()
suggestionsDebounceTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in suggestionsDebounceTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
let resource = self.accounts.api.searchSuggestions(query: query) let resource = self.accounts.api.searchSuggestions(query: query)
resource.addObserver(self.querySuggestions) resource.addObserver(self.querySuggestions)
@@ -99,9 +100,11 @@ final class SearchModel: ObservableObject {
if let suggestions: [String] = response.typedContent() { if let suggestions: [String] = response.typedContent() {
self.querySuggestions = Store<[String]>(suggestions) self.querySuggestions = Store<[String]>(suggestions)
} }
self.suggestionsText = query
} }
} else { } else {
self.querySuggestions = Store<[String]>(self.querySuggestions.collection) self.querySuggestions = Store<[String]>(self.querySuggestions.collection)
self.suggestionsText = query
} }
} }
} }

109
README.md
View File

@@ -2,16 +2,14 @@
Video player for [Invidious](https://github.com/iv-org/invidious) and [Piped](https://github.com/TeamPiped/Piped) instances built for iOS, tvOS and macOS. Video player for [Invidious](https://github.com/iv-org/invidious) and [Piped](https://github.com/TeamPiped/Piped) instances built for iOS, tvOS and macOS.
[![AGPL v3](https://shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0.en.html) [![AGPL v3](https://shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0.en.html)
[![GitHub issues](https://img.shields.io/github/issues/yattee/yattee)](https://github.com/yattee/yattee/issues) [![GitHub issues](https://img.shields.io/github/issues/yattee/yattee)](https://github.com/yattee/yattee/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/yattee/yattee)](https://github.com/yattee/yattee/pulls) [![GitHub pull requests](https://img.shields.io/github/issues-pr/yattee/yattee)](https://github.com/yattee/yattee/pulls)
[![Matrix](https://img.shields.io/matrix/yattee:matrix.org)](https://matrix.to/#/#yattee:matrix.org) [![Matrix](https://img.shields.io/matrix/yattee:matrix.org)](https://matrix.to/#/#yattee:matrix.org)
![Screenshot](https://r.yattee.stream/screenshots/all-platforms.png) ![Screenshot](https://r.yattee.stream/screenshots/all-platforms.png)
## Features ## Major Features
* Native user interface built with [SwiftUI](https://developer.apple.com/xcode/swiftui/) * Native user interface built with [SwiftUI](https://developer.apple.com/xcode/swiftui/)
* Multiple instances and accounts, fast switching * Multiple instances and accounts, fast switching
* [SponsorBlock](https://sponsor.ajay.app/), configurable categories to skip * [SponsorBlock](https://sponsor.ajay.app/), configurable categories to skip
@@ -37,104 +35,15 @@ Video player for [Invidious](https://github.com/iv-org/invidious) and [Piped](ht
| Subtitles | 🔴 | ✅ | | Subtitles | 🔴 | ✅ |
| Comments | 🔴 | ✅ | | Comments | 🔴 | ✅ |
## Installation You can browse and use accounts from one app and play videos with another (for example: use Invidious account for subscriptions and use Piped as playback source). Comments can be displayed from Piped even when Invidious is used for browsing/playing.
### Requirements
System requirements:
* iOS 14 (or newer)
* tvOS 15 (or newer)
* macOS Big Sur (or newer)
### How to install? ## Documentation
* [Installation Instructions](https://github.com/yattee/yattee/wiki/Installation-instructions)
#### macOS * [Integrations](https://github.com/yattee/yattee/wiki/Integrations)
Download and run latest version from the [Releases](https://github.com/yattee/yattee/releases) page. * [Screenshots Gallery](https://github.com/yattee/yattee/wiki/Screenshots-Gallery)
* [Tips](https://github.com/yattee/yattee/wiki/Tips)
#### iOS/tvOS: [AltStore](https://altstore.io/) (free) * [FAQ](https://github.com/yattee/yattee/wiki)
You can sideload IPA files downloaded from the [Releases](https://github.com/yattee/yattee/releases) page to your iOS or tvOS device - check [AltStore FAQ](https://altstore.io/faq/) for more information. * [Donations](https://github.com/yattee/yattee/wiki/Donations)
If you have to access to the beta AltStore version (v1.5, for Patreons only), you can add the following repository in `Browse > Sources` screen:
`https://alt.yattee.stream`
#### iOS/tvOS: Signing IPA files online (paid)
[UDID Registrations](https://www.udidregistrations.com/) provides services to sign IPA files for your devices. Refer to: ***Break free from the App Store*** section of the website for more information.
#### iOS/tvOS: Manual installation
Download sources and compile them on a Mac using Xcode, install to your devices. Please note that if you are not registered in Apple Developer Program you will need to reinstall every 7 days.
## Integrations
### macOS
With [Finicky](https://github.com/johnste/finicky) you can configure your system to open all the video links in the app. Example configuration:
```js
{
match: [
finicky.matchDomains(/(.*\.)?youtube.com/),
finicky.matchDomains(/(.*\.)?youtu.be/)
],
browser: "/Applications/Yattee.app"
}
```
## Screenshots
### iOS
| Player | Search | Playlists |
| - | - | - |
| [![Yattee Player iOS](https://r.yattee.stream/screenshots/iOS/player-thumb.png)](https://r.yattee.stream/screenshots/iOS/player.png) | [![Yattee Search iOS](https://r.yattee.stream/screenshots/iOS/search-suggestions-thumb.png)](https://r.yattee.stream/screenshots/iOS/search-suggestions.png) | [![Yattee Subscriptions iOS](https://r.yattee.stream/screenshots/iOS/playlists-thumb.png)](https://r.yattee.stream/screenshots/iOS/playlists.png) |
### iPadOS
| Settings | Player | Subscriptions |
| - | - | - |
| [![Yattee Player iPadOS](https://r.yattee.stream/screenshots/iPadOS/settings-thumb.png)](https://r.yattee.stream/screenshots/iPadOS/settings.png) | [![Yattee Player iPadOS](https://r.yattee.stream/screenshots/iPadOS/player-thumb.png)](https://r.yattee.stream/screenshots/iPadOS/player.png) | [![Yattee Subscriptions iPad S](https://r.yattee.stream/screenshots/iPadOS/subscriptions-thumb.png)](https://r.yattee.stream/screenshots/iPadOS/subscriptions.png) |
### tvOS
| Player | Popular | Search | Now Playing | Settings |
| - | - | - | - | - |
| [![Yattee Player tvOS](https://r.yattee.stream/screenshots/tvOS/player-thumb.png)](https://r.yattee.stream/screenshots/tvOS/player.png) | [![Yattee Popular tvOS](https://r.yattee.stream/screenshots/tvOS/popular-thumb.png)](https://r.yattee.stream/screenshots/tvOS/popular.png) | [![Yattee Search tvOS](https://r.yattee.stream/screenshots/tvOS/search-thumb.png)](https://r.yattee.stream/screenshots/tvOS/search.png) | [![Yattee Now Playing tvOS](https://r.yattee.stream/screenshots/tvOS/now-playing-thumb.png)](https://r.yattee.stream/screenshots/tvOS/now-playing.png) | [![Yattee Settings tvOS](https://r.yattee.stream/screenshots/tvOS/settings-thumb.png)](https://r.yattee.stream/screenshots/tvOS/settings.png) |
### macOS
| Player | Channel | Search | Settings |
| - | - | - | - |
| [![Yattee Player macOS](https://r.yattee.stream/screenshots/macOS/player-thumb.png)](https://r.yattee.stream/screenshots/macOS/player.png) | [![Yattee Channel macOS](https://r.yattee.stream/screenshots/macOS/channel-thumb.png)](https://r.yattee.stream/screenshots/macOS/channel.png) | [![Yattee Search macOS](https://r.yattee.stream/screenshots/macOS/search-thumb.png)](https://r.yattee.stream/screenshots/macOS/search.png) | [![Yattee Settings macOS](https://r.yattee.stream/screenshots/macOS/settings-thumb.png)](https://r.yattee.stream/screenshots/macOS/settings.png) |
## Tips
### Settings
* [tvOS] To open settings, press Play/Pause button while hovering over navigation menu or video
### Navigation
* Use videos context menus to add to queue, open or subscribe channel and add to playlist
* [tvOS] Pressing buttons in the app trigger switch to next available option (for example: next account in Settings). If you want to access list of all options, press and hold to open the context menu.
* [iOS] Swipe the player/title bar: up to open fullscreen details view, bottom to close fullscreen details or hide player
### Favorites
* Add more sections using ❤️ button in views channels, playlists, searches, subscriptions and popular
* [iOS/macOS] Reorganize with dragging and dropping
* [iOS/macOS] Remove section with right click/press and hold on section name
* [tvOS] Reorganize and remove from `Settings > Edit Favorites...`
### Keyboard shortcuts
* `Command+1` - Favorites
* `Command+2` - Subscriptions
* `Command+3` - Popular
* `Command+4` - Trending
* `Command+F` - Search
* `Command+P` - Play/Pause
* `Command+S` - Play Next
* `Command+O` - Toggle Player
## Donations
You can support development of this app with
[Patreon](https://www.patreon.com/arekf) or cryptocurrencies:
**Monero (XMR)**
```
48zfKjLmnXs21PinU2ucMiUPwhiKt5d7WJKiy3ACVS28BKqSn52c1TX8L337oESHJ5TZCyGkozjfWZG11h6C46mN9n4NPrD
```
**Bitcoin (BTC)**
```
bc1qe24zz5a5hm0trc7glwckz93py274eycxzju3mv
```
**Ethereum (ETH)**
```
0xa2f81A58Ec5E550132F03615c8d91954A4E37423
```
Donations will be used to cover development program access and domain renewal costs.
## Contributing ## Contributing
If you're interestred in contributing, you can browse the [issues](https://github.com/yattee/yattee/issues) list or create a new one to discuss your feature idea. Every contribution is very welcome. If you're interestred in contributing, you can browse the [issues](https://github.com/yattee/yattee/issues) list or create a new one to discuss your feature idea. Every contribution is very welcome.

View File

@@ -34,6 +34,9 @@ extension Defaults.Keys {
static let playerInstanceID = Key<Instance.ID?>("playerInstance") static let playerInstanceID = Key<Instance.ID?>("playerInstance")
static let showKeywords = Key<Bool>("showKeywords", default: false) static let showKeywords = Key<Bool>("showKeywords", default: false)
static let commentsInstanceID = Key<Instance.ID?>("commentsInstance", default: kavinPipedInstanceID) static let commentsInstanceID = Key<Instance.ID?>("commentsInstance", default: kavinPipedInstanceID)
#if !os(tvOS)
static let commentsPlacement = Key<CommentsPlacement>("commentsPlacement", default: .separate)
#endif
static let recentlyOpened = Key<[RecentItem]>("recentlyOpened", default: []) static let recentlyOpened = Key<[RecentItem]>("recentlyOpened", default: [])
@@ -129,3 +132,9 @@ enum VisibleSection: String, CaseIterable, Comparable, Defaults.Serializable {
lhs.sortOrder < rhs.sortOrder lhs.sortOrder < rhs.sortOrder
} }
} }
#if !os(tvOS)
enum CommentsPlacement: String, CaseIterable, Defaults.Serializable {
case info, separate
}
#endif

View File

@@ -66,6 +66,10 @@ struct FavoriteItemView: View {
#endif #endif
} }
} }
.onChange(of: accounts.current) { _ in
resource?.addObserver(store)
resource?.load()
}
} }
private var isVisible: Bool { private var isVisible: Bool {

View File

@@ -67,6 +67,7 @@ struct AppTabNavigation: View {
NavigationView { NavigationView {
ChannelPlaylistView(playlist: playlist) ChannelPlaylistView(playlist: playlist)
.environment(\.inNavigationView, true) .environment(\.inNavigationView, true)
.environmentObject(subscriptions)
.background(playerNavigationLink) .background(playerNavigationLink)
} }
} }

View File

@@ -45,11 +45,16 @@ final class PlayerViewController: UIViewController {
#if os(tvOS) #if os(tvOS)
playerModel.avPlayerViewController = playerViewController playerModel.avPlayerViewController = playerViewController
playerViewController.customInfoViewControllers = [ var infoViewControllers = [UIHostingController<AnyView>]()
infoViewController([.comments], title: "Comments"), if CommentsModel.enabled {
infoViewControllers.append(infoViewController([.comments], title: "Comments"))
}
infoViewControllers.append(contentsOf: [
infoViewController([.related], title: "Related"), infoViewController([.related], title: "Related"),
infoViewController([.playingNext, .playedPreviously], title: "Playing Next") infoViewController([.playingNext, .playedPreviously], title: "Playing Next")
] ])
playerViewController.customInfoViewControllers = infoViewControllers
#else #else
embedViewController() embedViewController()
#endif #endif

View File

@@ -65,7 +65,7 @@ struct VideoDetails: View {
} }
.padding(.horizontal) .padding(.horizontal)
if CommentsModel.enabled { if CommentsModel.enabled, CommentsModel.placement == .separate {
pagePicker pagePicker
.padding(.horizontal) .padding(.horizontal)
} }
@@ -245,13 +245,13 @@ struct VideoDetails: View {
Picker("Page", selection: $currentPage) { Picker("Page", selection: $currentPage) {
if !video.isNil { if !video.isNil {
Text("Info").tag(Page.info) Text("Info").tag(Page.info)
if !sidebarQueue { if CommentsModel.enabled, CommentsModel.placement == .separate {
Text("Related").tag(Page.related)
}
if CommentsModel.enabled {
Text("Comments") Text("Comments")
.tag(Page.comments) .tag(Page.comments)
} }
if !sidebarQueue {
Text("Related").tag(Page.related)
}
} }
if !sidebarQueue { if !sidebarQueue {
Text("Queue").tag(Page.queue) Text("Queue").tag(Page.queue)
@@ -366,65 +366,81 @@ struct VideoDetails: View {
var detailsPage: some View { var detailsPage: some View {
Group { Group {
if let video = player.currentItem?.video { Group {
Group { if let video = player.currentItem?.video {
HStack { Group {
publishedDateSection HStack {
Spacer() publishedDateSection
Spacer()
}
Divider()
countsSection
} }
Divider() Divider()
countsSection VStack(alignment: .leading, spacing: 10) {
} if let description = video.description {
Group {
Divider() if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
Text(description)
VStack(alignment: .leading, spacing: 10) { .textSelection(.enabled)
if let description = video.description { } else {
Group { Text(description)
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
Text(description)
.textSelection(.enabled)
} else {
Text(description)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.font(.system(size: 14))
.lineSpacing(3)
.padding(.bottom, 4)
} else {
Text("No description")
.foregroundColor(.secondary)
}
if showKeywords {
ScrollView(.horizontal, showsIndicators: showScrollIndicators) {
HStack {
ForEach(video.keywords, id: \.self) { keyword in
HStack(alignment: .center, spacing: 0) {
Text("#")
.font(.system(size: 11).bold())
Text(keyword)
.frame(maxWidth: 500)
}
.font(.caption)
.foregroundColor(.white)
.padding(.vertical, 4)
.padding(.horizontal, 8)
.background(Color("VideoDetailLikesSymbolColor"))
.mask(RoundedRectangle(cornerRadius: 3))
} }
} }
.padding(.bottom, 10) .frame(maxWidth: .infinity, alignment: .leading)
.font(.system(size: 14))
.lineSpacing(3)
} else {
Text("No description")
.foregroundColor(.secondary)
}
if showKeywords {
ScrollView(.horizontal, showsIndicators: showScrollIndicators) {
HStack {
ForEach(video.keywords, id: \.self) { keyword in
HStack(alignment: .center, spacing: 0) {
Text("#")
.font(.system(size: 11).bold())
Text(keyword)
.frame(maxWidth: 500)
}
.font(.caption)
.foregroundColor(.white)
.padding(.vertical, 4)
.padding(.horizontal, 8)
.background(Color("VideoDetailLikesSymbolColor"))
.mask(RoundedRectangle(cornerRadius: 3))
}
}
.padding(.bottom, 10)
}
} }
} }
} }
if !video.isNil, CommentsModel.placement == .info {
Divider()
#if os(macOS)
.padding(.bottom, 20)
#else
.padding(.vertical, 10)
#endif
}
}
.padding(.horizontal)
Group {
if !video.isNil, CommentsModel.placement == .info {
CommentsView()
}
} }
} }
.padding(.horizontal)
} }
func videoDetail(label: String, value: String, symbol: String) -> some View { func videoDetail(label: String, value: String, symbol: String) -> some View {

View File

@@ -37,6 +37,7 @@ struct SearchTextField: View {
} }
} }
#if os(macOS) #if os(macOS)
.frame(maxWidth: 190)
.textFieldStyle(.plain) .textFieldStyle(.plain)
#else #else
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
@@ -52,6 +53,11 @@ struct SearchTextField: View {
.padding(.trailing) .padding(.trailing)
#endif #endif
clearButton clearButton
} else {
#if os(macOS)
clearButton
.opacity(0)
#endif
} }
} }
} }

View File

@@ -14,8 +14,9 @@ struct SearchSuggestions: View {
recents.addQuery(state.queryText) recents.addQuery(state.queryText)
} label: { } label: {
HStack(spacing: 5) { HStack {
Label(state.queryText, systemImage: "magnifyingglass") Image(systemName: "magnifyingglass")
Text(state.queryText)
.lineLimit(1) .lineLimit(1)
} }
} }
@@ -27,15 +28,19 @@ struct SearchSuggestions: View {
Button { Button {
state.queryText = suggestion state.queryText = suggestion
} label: { } label: {
HStack(spacing: 0) { HStack {
Label(state.queryText, systemImage: "arrow.up.left.circle") Image(systemName: "arrow.up.left.circle")
.lineLimit(1)
.layoutPriority(2)
.foregroundColor(.secondary) .foregroundColor(.secondary)
HStack(spacing: 0) {
Text(state.suggestionsText)
.lineLimit(1)
.layoutPriority(2)
.foregroundColor(.secondary)
Text(querySuffix(suggestion)) Text(querySuffix(suggestion))
.lineLimit(1) .lineLimit(1)
.layoutPriority(1) .layoutPriority(1)
}
} }
} }
#if os(macOS) #if os(macOS)
@@ -55,7 +60,7 @@ struct SearchSuggestions: View {
} }
private func querySuffix(_ suggestion: String) -> String { private func querySuffix(_ suggestion: String) -> String {
suggestion.replacingFirstOccurrence(of: state.queryText.lowercased(), with: "") suggestion.replacingFirstOccurrence(of: state.suggestionsText.lowercased(), with: "")
} }
#if os(macOS) #if os(macOS)

View File

@@ -6,9 +6,17 @@ struct ServicesSettings: View {
@Default(.sponsorBlockCategories) private var sponsorBlockCategories @Default(.sponsorBlockCategories) private var sponsorBlockCategories
@Default(.commentsInstanceID) private var commentsInstanceID @Default(.commentsInstanceID) private var commentsInstanceID
#if !os(tvOS)
@Default(.commentsPlacement) private var commentsPlacement
#endif
var body: some View { var body: some View {
Section(header: SettingsHeader(text: "Comments")) { Section(header: SettingsHeader(text: "Comments")) {
commentsInstancePicker commentsInstancePicker
#if !os(tvOS)
commentsPlacementPicker
.disabled(!CommentsModel.enabled)
#endif
} }
Section(header: SettingsHeader(text: "SponsorBlock API")) { Section(header: SettingsHeader(text: "SponsorBlock API")) {
@@ -58,7 +66,7 @@ struct ServicesSettings: View {
} }
private var commentsInstancePicker: some View { private var commentsInstancePicker: some View {
Picker("Comments", selection: $commentsInstanceID) { Picker("Source", selection: $commentsInstanceID) {
Text("Disabled").tag(Optional("")) Text("Disabled").tag(Optional(""))
ForEach(InstancesModel.all.filter { $0.app.supportsComments }) { instance in ForEach(InstancesModel.all.filter { $0.app.supportsComments }) { instance in
@@ -73,6 +81,19 @@ struct ServicesSettings: View {
#endif #endif
} }
#if !os(tvOS)
private var commentsPlacementPicker: some View {
Picker("Placement", selection: $commentsPlacement) {
Text("Below video description").tag(CommentsPlacement.info)
Text("Separate tab").tag(CommentsPlacement.separate)
}
.labelsHidden()
#if os(iOS)
.pickerStyle(.automatic)
#endif
}
#endif
func toggleCategory(_ category: String, value: Bool) { func toggleCategory(_ category: String, value: Bool) {
if let index = sponsorBlockCategories.firstIndex(where: { $0 == category }), !value { if let index = sponsorBlockCategories.firstIndex(where: { $0 == category }), !value {
sponsorBlockCategories.remove(at: index) sponsorBlockCategories.remove(at: index)

View File

@@ -2277,7 +2277,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements"; CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -2311,7 +2311,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements"; CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -2343,7 +2343,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -2375,7 +2375,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -2538,7 +2538,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -2569,7 +2569,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -2604,7 +2604,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -2637,7 +2637,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -2768,7 +2768,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -2800,7 +2800,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7; CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;