Skip to content

Commit

Permalink
Theming whitelabel.py script (#214)
Browse files Browse the repository at this point in the history
* chore: added whitelabel script, added login background color

* style: added rounded corner FF

* chore: changed assets for progress bar and unibutton color

* chore: added multiple assets supporting

* chore: move whitelabel config into config repo

* chore: moved extra Assets to Theme target

* chore: return back splash screen background color

* chore: added logs for whitelabel script

* chore: rounded buttons theming

* chore: changes in whitelabel script

* chore: fix after merge

* chore: added themed button shape for social login buttons

* style: add login navigation text color as separate

* chore: added app icon changing

* chore: add comment

* chore: added bundle id changing

* chore: set dev team in project file

* chore: got rid original images names from config, now read from Content.json

* chore: reorder configs

* chore: added documentation

* chore: missed quotes

* refactor: theme config

* chore: backbutton color on sign in view

* chore: fixed misspelling

* refactor: change to snake_style stage1

* refactor: changed to snake_style stage2

* chore: added app versions, refactor and unify code to search parameters in project file

* chore: added install dependencies to documentation

* chore: fixed according feedback, improved documentation

* chore: fixed how to get config example

* chore: improve documentation
  • Loading branch information
rnr authored Jan 2, 2024
1 parent d857e3b commit 1bc4a75
Show file tree
Hide file tree
Showing 21 changed files with 725 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct SignInView: View {
VStack {
Button(action: { viewModel.router.back() }, label: {
CoreAssets.arrowLeft.swiftUIImage.renderingMode(.template)
.backButtonStyle(color: .white)
.backButtonStyle(color: Theme.Colors.loginNavigationText)
})
.foregroundColor(Theme.Colors.styledButtonText)
.padding(.leading, isHorizontal ? 48 : 0)
Expand Down Expand Up @@ -141,7 +141,7 @@ public struct SignInView: View {
}
.padding(.horizontal, 24)
.padding(.top, 50)
}.roundedBackground(Theme.Colors.background)
}.roundedBackground(Theme.Colors.loginBackground)
.scrollAvoidKeyboard(dismissKeyboardByTap: true)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ public struct SignUpView: View {
ZStack {
HStack {
Text(CoreLocalization.SignIn.registerBtn)
.titleSettings(color: Theme.Colors.white)
.titleSettings(color: Theme.Colors.loginNavigationText)
}
VStack {
Button(action: { viewModel.router.back() }, label: {
CoreAssets.arrowLeft.swiftUIImage.renderingMode(.template)
.backButtonStyle(color: Theme.Colors.white)
.backButtonStyle(color: Theme.Colors.loginNavigationText)
})
.foregroundColor(Theme.Colors.styledButtonText)
.padding(.leading, isHorizontal ? 48 : 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public struct ResetPasswordView: View {

VStack(alignment: .center) {
NavigationBar(title: AuthLocalization.Forgot.title,
titleColor: Theme.Colors.white,
leftButtonColor: Theme.Colors.white,
titleColor: Theme.Colors.loginNavigationText,
leftButtonColor: Theme.Colors.loginNavigationText,
leftButtonAction: {
viewModel.router.back()
}).padding(.leading, isHorizontal ? 48 : 0)
Expand Down
4 changes: 4 additions & 0 deletions Core/Core.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
0770DE5F28D0B22C006D8A5D /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0770DE5E28D0B22C006D8A5D /* Strings.swift */; };
0770DE6128D0B2CB006D8A5D /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0770DE6028D0B2CB006D8A5D /* Assets.swift */; };
07DDFCBD29A780BB00572595 /* UINavigationController+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07DDFCBC29A780BB00572595 /* UINavigationController+Animation.swift */; };
A53A32352B233DEC005FE38A /* ThemeConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A32342B233DEC005FE38A /* ThemeConfig.swift */; };
BA30427F2B20B320009B64B7 /* SocialAuthError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA30427D2B20B299009B64B7 /* SocialAuthError.swift */; };
BA76135C2B21BC7300B599B7 /* SocialAuthResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA76135B2B21BC7300B599B7 /* SocialAuthResponse.swift */; };
BA8B3A2F2AD546A700D25EF5 /* DebugLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA8B3A2E2AD546A700D25EF5 /* DebugLog.swift */; };
Expand Down Expand Up @@ -291,6 +292,7 @@
3B74C6685E416657F3C5F5A8 /* Pods-App-Core.releaseprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Core.releaseprod.xcconfig"; path = "Target Support Files/Pods-App-Core/Pods-App-Core.releaseprod.xcconfig"; sourceTree = "<group>"; };
60153262DBC2F9E660D7E11B /* Pods-App-Core.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Core.release.xcconfig"; path = "Target Support Files/Pods-App-Core/Pods-App-Core.release.xcconfig"; sourceTree = "<group>"; };
9D5B06CAA99EA5CD49CBE2BB /* Pods-App-Core.debugdev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Core.debugdev.xcconfig"; path = "Target Support Files/Pods-App-Core/Pods-App-Core.debugdev.xcconfig"; sourceTree = "<group>"; };
A53A32342B233DEC005FE38A /* ThemeConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeConfig.swift; sourceTree = "<group>"; };
BA30427D2B20B299009B64B7 /* SocialAuthError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocialAuthError.swift; sourceTree = "<group>"; };
BA76135B2B21BC7300B599B7 /* SocialAuthResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialAuthResponse.swift; sourceTree = "<group>"; };
BA8B3A2E2AD546A700D25EF5 /* DebugLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugLog.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -707,6 +709,7 @@
BAFB99832B0E282E007D09F9 /* MicrosoftConfig.swift */,
BAFB998F2B14B377007D09F9 /* GoogleConfig.swift */,
BAFB99912B14E23D007D09F9 /* AppleSignInConfig.swift */,
A53A32342B233DEC005FE38A /* ThemeConfig.swift */,
);
path = Config;
sourceTree = "<group>";
Expand Down Expand Up @@ -1040,6 +1043,7 @@
024BE3DF29B2615500BCDEE2 /* CGColorExtension.swift in Sources */,
0770DE6128D0B2CB006D8A5D /* Assets.swift in Sources */,
0727878928D31734002E9142 /* User.swift in Sources */,
A53A32352B233DEC005FE38A /* ThemeConfig.swift in Sources */,
02280F5B294B4E6F0032823A /* Connectivity.swift in Sources */,
02066B482906F73400F4307E /* PickerMenu.swift in Sources */,
);
Expand Down
1 change: 1 addition & 0 deletions Core/Core/Configuration/Config/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public protocol ConfigProtocol {
var google: GoogleConfig { get }
var appleSignIn: AppleSignInConfig { get }
var features: FeaturesConfig { get }
var theme: ThemeConfig { get }
var uiComponents: UIComponentsConfig { get }
}

Expand Down
28 changes: 28 additions & 0 deletions Core/Core/Configuration/Config/ThemeConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// ThemeConfig.swift
// Core
//
// Created by Anton Yarmolenka on 01/12/2023.
//

import Foundation

private enum ThemeKeys: String {
case isRoundedCorners = "ROUNDED_CORNERS_STYLE"
}

public final class ThemeConfig: NSObject {
public var isRoundedCorners: Bool

init(dictionary: [String: AnyObject]) {
isRoundedCorners = dictionary[ThemeKeys.isRoundedCorners.rawValue] as? Bool != false
super.init()
}
}

private let ThemeKey = "THEME"
extension Config {
public var theme: ThemeConfig {
ThemeConfig(dictionary: self[ThemeKey] as? [String: AnyObject] ?? [:])
}
}
2 changes: 1 addition & 1 deletion Core/Core/View/Base/ProgressBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public struct ProgressBar: View {
ZStack {
Circle()
.stroke(lineWidth: lineWidth)
.foregroundColor(Color.blue.opacity(0.3))
.foregroundColor(Theme.Colors.accentColor.opacity(0.3))
.frame(width: size, height: size)

Circle()
Expand Down
3 changes: 2 additions & 1 deletion Core/Core/View/Base/SocialAuthButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import Theme

public struct SocialAuthButton: View {

Expand Down Expand Up @@ -54,7 +55,7 @@ public struct SocialAuthButton: View {
.frame(maxWidth: idiom == .pad ? 260: .infinity, minHeight: 42)
.background(backgroundColor)
.clipShape(
RoundedRectangle(cornerRadius: cornerRadius)
Theme.Shapes.buttonShape
)

}
Expand Down
9 changes: 5 additions & 4 deletions Core/Core/View/Base/StyledButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public struct StyledButton: View {
public init(_ title: String,
action: @escaping () -> Void,
isTransparent: Bool = false,
color: Color = Theme.Colors.accentColor,
color: Color = Theme.Colors.accentButtonColor,
textColor: Color = Theme.Colors.styledButtonText,
disabledTextColor: Color = Theme.Colors.textPrimary,
borderColor: Color = .clear,
Expand Down Expand Up @@ -58,9 +58,10 @@ public struct StyledButton: View {
.fill(isTransparent ? .clear : buttonColor)
)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(style: .init(lineWidth: 1, lineCap: .round, lineJoin: .round, miterLimit: 1))
.foregroundColor(isTransparent ? Theme.Colors.white : borderColor)
Theme.Shapes.buttonShape
.stroke(style: .init(lineWidth: 1, lineCap: .round, lineJoin: .round, miterLimit: 1))
.foregroundColor(isTransparent ? Theme.Colors.white : borderColor)

)
.accessibilityElement(children: .ignore)
.accessibilityLabel(title)
Expand Down
12 changes: 6 additions & 6 deletions Core/Core/View/Base/UnitButtonView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,22 @@ public struct UnitButtonView: View {
Theme.Shapes.buttonShape
.fill(type == .previous
? Theme.Colors.background
: Theme.Colors.accentColor)
: Theme.Colors.accentButtonColor)
.shadow(color: Color.black.opacity(0.25), radius: 21, y: 4)
.overlay(
RoundedRectangle(cornerRadius: 8)
Theme.Shapes.buttonShape
.stroke(style: .init(
lineWidth: 1,
lineCap: .round,
lineJoin: .round,
miterLimit: 1)
)
.foregroundColor(Theme.Colors.accentColor)
.foregroundColor(Theme.Colors.accentButtonColor)
)

case .continueLesson, .nextSection, .reload, .finish, .custom:
Theme.Shapes.buttonShape
.fill(bgColor ?? Theme.Colors.accentColor)
.fill(bgColor ?? Theme.Colors.accentButtonColor)

.shadow(color: (type == .first
|| type == .next
Expand All @@ -168,14 +168,14 @@ public struct UnitButtonView: View {
|| type == .reload) ? Color.black.opacity(0.25) : .clear,
radius: 21, y: 4)
.overlay(
RoundedRectangle(cornerRadius: 8)
Theme.Shapes.buttonShape
.stroke(style: .init(
lineWidth: 1,
lineCap: .round,
lineJoin: .round,
miterLimit: 1
))
.foregroundColor(Theme.Colors.accentColor)
.foregroundColor(Theme.Colors.accentButtonColor)
)
}
}
Expand Down
80 changes: 80 additions & 0 deletions Documentation/Theming_implementation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Theming Implementation
This documentation provides instructions on how to implement Theme assets for the OpenEdX iOS project.

## Python dependecies
The `whitelabel.py` theming script requires the following Python dependencies to be installed:
- `pip3 install coloredlogs`
- `pip3 install pillow`
- `pip3 install pyyaml`

## How to Run the Script
The theming script `whitelabel.py` can be run from the OpenEdX iOS root project folder with the following command:
```bash
python3 config_script/whitelabel.py --config-file=path/to/configfile/whitelabel.yaml -v
```
where
- `config_script/whitelabel.py` is the path to the `whitelabel.py` script
- `--config-file=path/to/configfile/whitelabel.yaml` is the path to the configuration file `whitelabel.yaml`
- `-v` sets the log level (all messages if '-v' is present and errors only if is not).

## Example of whitelabel.yaml
You can get example of `whitelabel.yaml` file by run next command:
```bash
python3 config_script/whitelabel.py --help-config-file
```
Just copy script's output to your `whitelabel.yaml` file.

## Config Options
The config file `whitelabel.yaml` can be created by yourself or obtained from some config repo.
This config can contain the following options:
### Folder with source assets
This is the folder where all image assets, which should be copied into the project, are placed (can be relative or absolute):
```yaml
import_dir: 'path/to/images/source'
```
### Xcode Project Settings
The theming script can change the app name, version, development team and app bundle ID:
```yaml
project_config:
project_path: 'path/to/project/project.pbxproj' # path to project.pbxproj file
dev_team: '1234567890' # Apple development team ID
marketing_version: '1.0.1' # App marketing version
current_project_version: '2' # App build number
configurations:
config1: # Build Configuration name in project
app_bundle_id: "bundle.id.app.new1" # Bundle ID to be set
product_name: "Mobile App Name1" # App Name to be set
config2: # Build Configuration name in project
app_bundle_id: "bundle.id.app.new2" # Bundle ID to be set
product_name: "Mobile App Name2" # App Name to be set
```
### Assets
The config `whitelabel.yaml` can contain a few Asset items (every added Xcode project can have its own Assets).
Every Asset item can be configured with images, colors, and app Icon Assets:
```yaml
assets:
AssetName:
images_path: 'Theme/Theme/Assets.xcassets' # path where images are placed in this Asset
colors_path: 'Theme/Theme/Assets.xcassets/Colors' # path where colors are placed in this Asset
icon_path: 'Theme/Assets.xcassets' # path where app icon is placed in this Asset
images:
image1: # Asset name
image_name: 'some_image.svg' # image to replace the existing one for image1 Asset (light/universal)
image2: # Asset name
current_path: 'SomeFolder' # Path to image2.imageset inside Assets.xcassets
image_name: 'Rectangle.png' # image to replace the existing one for image2 Asset (light/universal)
dark_image_name: 'RectangleDark.png' # image to replace the existing dark appearance for image2 Asset (dark)
colors:
LoginBackground: # color asset name in Assets
current_path: '' # optional: path to color inside colors_path
light: '#FFFFFF'
dark: '#ED5C13'
icon:
AppIcon:
current_path: '' # optional: path to icon inside icon_path
image_name: 'appIcon.jpg' # image to replace the current AppIcon - png or jpg are supported
```
### Log level
You can set the log level to 'DEBUG' by adding the `-v` parameter to the script running.
The default log level is 'WARN'
##
2 changes: 1 addition & 1 deletion OpenEdX/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
initDI()

if let config = Container.shared.resolve(ConfigProtocol.self) {
Theme.Shapes.isRoundedCorners = config.theme.isRoundedCorners
if let configuration = config.firebase.firebaseOptions {
FirebaseApp.configure(options: configuration)
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
}

if config.facebook.enabled {
ApplicationDelegate.shared.application(
application,
Expand Down
10 changes: 5 additions & 5 deletions OpenEdX/Base.lproj/LaunchScreen.storyboard
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand All @@ -26,7 +26,7 @@
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" name="SplachBackground"/>
<color key="backgroundColor" name="SplashBackground"/>
<constraints>
<constraint firstItem="N54-4c-KWq" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="deh-AL-9fZ"/>
<constraint firstItem="N54-4c-KWq" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="gzk-ry-JKk"/>
Expand All @@ -39,8 +39,8 @@
</scene>
</scenes>
<resources>
<image name="appLogo" width="1024" height="1024"/>
<namedColor name="SplachBackground">
<image name="appLogo" width="171" height="48"/>
<namedColor name="SplashBackground">
<color red="0.31764705882352939" green="0.4823529411764706" blue="0.99607843137254903" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "0.408",
"red" : "0.235"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.976",
"green" : "0.471",
"red" : "0.329"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading

0 comments on commit 1bc4a75

Please sign in to comment.