Skip to content
Merged
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
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,35 +49,37 @@ Images can be local (asset name without `http`) or remote (full URL).

### Customizing Text and Translation

All user-facing strings are managed through `Localizable.xcstrings` (the String Catalog). Open it in Xcode to change the default English text or add new languages — no code changes required.
All user-facing strings are managed through `Localizable.xcstrings` (the String Catalog). Open it in Xcode to change the default English text or add new languages. No code changes required.

## Dependencies

- [FRadioPlayer](https://github.com/fethica/FRadioPlayer) streaming and metadata
- [LNPopupController](https://github.com/LeoNatan/LNPopupController) now playing popup bar
- [NVActivityIndicatorView](https://github.com/ninjaprox/NVActivityIndicatorView) loading indicators
- [MarqueeLabel](https://github.com/cbpowell/MarqueeLabel) scrolling text labels
- [FRadioPlayer](https://github.com/fethica/FRadioPlayer) --streaming and metadata
- [LNPopupController](https://github.com/LeoNatan/LNPopupController) --now playing popup bar
- [NVActivityIndicatorView](https://github.com/ninjaprox/NVActivityIndicatorView) --loading indicators
- [MarqueeLabel](https://github.com/cbpowell/MarqueeLabel) --scrolling text labels

All managed via Swift Package Manager.

## Contributing

Contributions are welcome. Please branch off [`dev`](https://github.com/analogcode/Swift-Radio-Pro/tree/dev) and open a pull request do not commit directly to `master`.
Contributions are welcome. Please branch off [`dev`](https://github.com/analogcode/Swift-Radio-Pro/tree/dev) and open a pull request --do not commit directly to `master`.

## Single Station Version

Looking for a simpler, single-station version of this app? We offer a ready-to-go codebase for **$50** — no extra fees.
Looking for a simpler, single-station version? It skips the station list and launches straight into the player.

PayPal [fethica@me.com](mailto:fethica@me.com) or use [PayPal.Me](https://www.paypal.me/fethicaEH), and we will send the code within 24 hours with setup instructions. All funds support the project.
[![Buy on Payhip](https://img.shields.io/badge/Buy-Single%20Station-blue)](https://payhip.com/b/x15QB)

All proceeds go directly toward maintaining and improving Swift Radio.

For custom work or more advanced needs, reach out to [Fethi](mailto:contact@fethica.com).

**Built something with Swift Radio?** We'd love to see it drop us a line at [contact@fethica.com](mailto:contact@fethica.com).
**Built something with Swift Radio?** We'd love to see it --drop us a line at [contact@fethica.com](mailto:contact@fethica.com).

## Credits

- [Fethi](https://fethica.com) co-organizer and lead developer
- [Matthew Fecher](http://matthewfecher.com) creator, [AudioKit Pro](https://audiokitpro.com)
- [Fethi](https://fethica.com) --co-organizer and lead developer
- [Matthew Fecher](http://matthewfecher.com) --creator, [AudioKit Pro](https://audiokitpro.com)
- [All contributors](https://github.com/analogcode/Swift-Radio-Pro/graphs/contributors)

## License
Expand Down
14 changes: 7 additions & 7 deletions SwiftRadio/Config/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,25 @@ struct Config {
struct About {
static let sections: [InfoSection] = [
InfoSection(title: Content.About.Sections.features, items: [
.features()
.features(title: Content.About.Items.features)
]),
InfoSection(title: Content.About.Sections.contact, items: [
.email(address: Config.email),
.email(title: Content.About.Items.email, address: Config.email),
.link(title: Content.About.feedback.0, subtitle: Content.About.feedback.1, url: Config.feedbackURL)
]),
InfoSection(title: Content.About.Sections.support, items: [
.rateApp(appID: "YOUR_APP_ID"),
.share(text: Content.About.shareText)
.rateApp(title: Content.About.Items.rateApp, appID: "YOUR_APP_ID"),
.share(title: Content.About.Items.shareApp, text: Content.About.shareText)
]),
InfoSection(title: Content.About.Sections.credits, items: [
.libraries(),
.credits(owner: "analogcode", repo: "Swift-Radio-Pro")
.libraries(title: Content.About.Items.libraries),
.credits(title: Content.About.Items.contributors, subtitle: Content.About.Items.specialThanks, owner: "analogcode", repo: "Swift-Radio-Pro")
]),
InfoSection(title: Content.About.Sections.legal, items: [
.link(title: Content.About.license.0, subtitle: Content.About.license.1, url: Config.licenseURL)
]),
InfoSection(title: Content.About.Sections.version, items: [
.version()
.version(title: Content.About.Items.appVersion)
])
]
}
Expand Down
13 changes: 13 additions & 0 deletions SwiftRadio/Config/Content.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,22 @@ struct Content {
static let version = String(localized: "about.sections.version")
}

static let copyright = String(localized: "about.copyright")

static let feedback = (String(localized: "about.feedback.title"), String(localized: "about.feedback.message"))
static let shareText = String(localized: "about.shareText")
static let license = (String(localized: "about.license.title"), String(localized: "about.license.detail"))

struct Items {
static let features = String(localized: "about.items.features")
static let email = String(localized: "about.items.email")
static let rateApp = String(localized: "about.items.rateApp")
static let shareApp = String(localized: "about.items.shareApp")
static let libraries = String(localized: "about.items.libraries")
static let contributors = String(localized: "about.items.contributors")
static let specialThanks = String(localized: "about.items.specialThanks")
static let appVersion = String(localized: "about.items.appVersion")
}
}

struct Contributors {
Expand Down
99 changes: 99 additions & 0 deletions SwiftRadio/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@
}
}
},
"about.copyright" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Copyright"
}
}
}
},
"about.footerAuthors" : {
"extractionState" : "manual",
"localizations" : {
Expand All @@ -45,6 +56,94 @@
}
}
},
"about.items.appVersion" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "App Version"
}
}
}
},
"about.items.contributors" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Contributors"
}
}
}
},
"about.items.email" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Email"
}
}
}
},
"about.items.features" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Features"
}
}
}
},
"about.items.libraries" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open Source Libraries"
}
}
}
},
"about.items.rateApp" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rate the App"
}
}
}
},
"about.items.shareApp" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Share the App"
}
}
}
},
"about.items.specialThanks" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Special Thanks"
}
}
}
},
"about.headerText" : {
"extractionState" : "manual",
"localizations" : {
Expand Down
2 changes: 1 addition & 1 deletion SwiftRadio/ViewControllers/AboutViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class AboutViewController: UITableViewController {
footerLabel.text =
"""
\(Content.About.footerAuthors)
Copyright © \(Calendar.current.component(.year, from: Date())) \(Content.About.footerCopyright)
\(Content.About.copyright) © \(Calendar.current.component(.year, from: Date())) \(Content.About.footerCopyright)
"""

stackView.addArrangedSubview(logoImageView)
Expand Down