Skip to content

Commit 3a90b53

Browse files
authored
Merge pull request #2743 from StoDevX/radio-theming
Support Radio theming
2 parents ba723b3 + 6bb2db2 commit 3a90b53

File tree

9 files changed

+434
-112
lines changed

9 files changed

+434
-112
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
]
7575
},
7676
"dependencies": {
77+
"@callstack/react-theme-provider": "1.0.3",
7778
"@hawkrives/react-native-alphabetlistview": "1.0.0",
7879
"@hawkrives/react-native-alternate-icons": "0.4.7",
7980
"@hawkrives/react-native-sortable-list": "1.0.1",

source/views/components/colors.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,6 @@ export const tableviewAccessoryColor = 'rgb(0, 122, 255)'
4848

4949
export const semitransparentGray = 'rgba(0,0,0,0.2)'
5050

51-
// MARK: Oleville colors
52-
export const theLatest = '#00BFFF'
53-
export const olevilleGold = '#FFC107'
54-
export const darkGold = '#c79100'
55-
export const olevilleBackground = '#F0F0E1'
56-
57-
// MARK: KSTO Colors
58-
export const kstoPrimaryLight = '#c5c5e8'
59-
export const kstoSecondaryLight = '#7789bb'
60-
export const kstoPrimaryDark = '#686ea1'
61-
export const kstoSecondaryDark = '#4c4f71'
62-
export const kstoTextLight = '#dcdde5'
63-
export const kstoTextDark = '#bebad4'
64-
6551
// MARK: System Colors
6652
export const infoBlue = 'rgb(47, 112, 225)'
6753
export const success = 'rgb(83, 215, 106)'

source/views/streaming/index.js

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,20 @@
11
// @flow
22

3-
import * as React from 'react'
43
import {TabNavigator} from '../components/tabbed-view'
5-
import {TabBarIcon} from '../components/tabbar-icon'
64

7-
import {RadioControllerView} from './radio'
85
// import WeeklyMovieView from './movie'
96
import {WebcamsView} from './webcams'
107
import {StreamListView} from './streams'
11-
import * as logos from '../../../images/streaming'
8+
import {KstoStationView} from './radio/station-ksto'
9+
import {KrlxStationView} from './radio/station-krlx'
1210

1311
export {KSTOScheduleView, KRLXScheduleView} from './radio'
1412

1513
const StreamingMediaView = TabNavigator({
1614
StreamingView: {screen: StreamListView},
1715
LiveWebcamsView: {screen: WebcamsView},
18-
KSTORadioView: {
19-
screen: ({navigation}) => (
20-
<RadioControllerView
21-
image={logos.ksto}
22-
imageBorder={false}
23-
navigation={navigation}
24-
playerUrl="https://www.stolaf.edu/multimedia/play/embed/ksto.html"
25-
scheduleViewName="KSTOScheduleView"
26-
source={{
27-
useEmbeddedPlayer: true,
28-
embeddedPlayerUrl:
29-
'https://www.stolaf.edu/multimedia/play/embed/ksto.html',
30-
streamSourceUrl: '',
31-
}}
32-
stationName="KSTO 93.1 FM"
33-
stationNumber="+15077863602"
34-
title="St. Olaf College Radio"
35-
/>
36-
),
37-
navigationOptions: {
38-
tabBarLabel: 'KSTO',
39-
tabBarIcon: TabBarIcon('radio'),
40-
},
41-
},
42-
KRLXRadioView: {
43-
screen: ({navigation}) => (
44-
<RadioControllerView
45-
image={logos.krlx}
46-
imageBorder={true}
47-
navigation={navigation}
48-
playerUrl="http://live.krlx.org"
49-
scheduleViewName="KRLXScheduleView"
50-
source={{
51-
useEmbeddedPlayer: false,
52-
embeddedPlayerUrl: 'http://live.krlx.org',
53-
streamSourceUrl: 'http://radio.krlx.org/mp3/high_quality',
54-
}}
55-
stationName="88.1 KRLX-FM"
56-
stationNumber="+15072224127"
57-
title="Carleton College Radio"
58-
/>
59-
),
60-
navigationOptions: {
61-
tabBarLabel: 'KRLX',
62-
tabBarIcon: TabBarIcon('microphone'),
63-
},
64-
},
16+
KSTORadioView: {screen: KstoStationView},
17+
KRLXRadioView: {screen: KrlxStationView},
6518
// WeeklyMovieView: {screen: WeeklyMovieView},
6619
})
6720

source/views/streaming/radio/buttons.js

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,45 @@ import {StyleSheet, Text, View, Platform} from 'react-native'
55
import * as c from '../../components/colors'
66
import Icon from 'react-native-vector-icons/Ionicons'
77
import {Touchable} from '../../components/touchable'
8+
import {withTheme} from '@callstack/react-theme-provider'
9+
import type {PlayerTheme} from './types'
810

911
type ActionButtonProps = {
1012
icon: string,
1113
text: string,
1214
onPress: () => mixed,
15+
theme: PlayerTheme,
1316
}
1417

15-
export const ActionButton = ({icon, text, onPress}: ActionButtonProps) => (
16-
<Touchable highlight={false} onPress={onPress} style={styles.button}>
17-
<View style={styles.wrapper}>
18-
<Icon name={icon} style={styles.icon} />
19-
<Text style={styles.action}>{text}</Text>
20-
</View>
21-
</Touchable>
22-
)
18+
const ActionButton = (props: ActionButtonProps) => {
19+
let {icon, text, onPress, theme} = props
20+
let bg = {backgroundColor: theme.tintColor}
21+
let fg = {color: theme.buttonTextColor}
22+
let style = [styles.button, styles.largeButton, bg]
23+
24+
return (
25+
<Touchable highlight={false} onPress={onPress} style={style}>
26+
<View style={styles.wrapper}>
27+
<Icon name={icon} style={[styles.icon, fg]} />
28+
<Text style={[styles.action, fg]}>{text}</Text>
29+
</View>
30+
</Touchable>
31+
)
32+
}
33+
34+
const ThemedActionButton = withTheme(ActionButton)
35+
36+
export {ThemedActionButton as ActionButton}
2337

2438
export const CallButton = ({onPress}: {onPress: () => mixed}) => (
25-
<SmallActionButton
39+
<ThemedSmallActionButton
2640
icon={Platform.OS === 'ios' ? 'ios-call' : 'md-call'}
2741
onPress={onPress}
2842
/>
2943
)
3044

3145
export const ShowCalendarButton = ({onPress}: {onPress: () => mixed}) => (
32-
<SmallActionButton
46+
<ThemedSmallActionButton
3347
icon={Platform.OS === 'ios' ? 'ios-calendar' : 'md-calendar'}
3448
onPress={onPress}
3549
/>
@@ -38,36 +52,42 @@ export const ShowCalendarButton = ({onPress}: {onPress: () => mixed}) => (
3852
type SmallActionButtonProps = {
3953
icon: string,
4054
onPress: () => mixed,
55+
theme: PlayerTheme,
4156
}
4257

43-
const SmallActionButton = ({icon, onPress}: SmallActionButtonProps) => (
44-
<Touchable highlight={false} onPress={onPress} style={styles.smallButton}>
45-
<View style={styles.wrapper}>
46-
<Icon name={icon} style={styles.icon} />
47-
</View>
48-
</Touchable>
49-
)
58+
const SmallActionButton = (props: SmallActionButtonProps) => {
59+
let {icon, onPress, theme} = props
60+
let bg = {backgroundColor: theme.tintColor}
61+
let fg = {color: theme.buttonTextColor}
62+
let style = [styles.button, styles.smallButton, bg]
63+
64+
return (
65+
<Touchable highlight={false} onPress={onPress} style={style}>
66+
<Icon name={icon} style={[styles.icon, fg]} />
67+
</Touchable>
68+
)
69+
}
70+
71+
const ThemedSmallActionButton = withTheme(SmallActionButton)
5072

5173
const styles = StyleSheet.create({
5274
button: {
5375
alignItems: 'center',
5476
paddingVertical: 5,
55-
backgroundColor: c.denim,
56-
width: 180,
57-
borderRadius: 8,
58-
overflow: 'hidden',
59-
},
60-
smallButton: {
61-
alignItems: 'center',
62-
paddingVertical: 5,
63-
backgroundColor: c.denim,
64-
width: 50,
6577
borderRadius: 8,
6678
overflow: 'hidden',
79+
backgroundColor: c.black,
6780
},
6881
wrapper: {
82+
justifyContent: 'center',
6983
flexDirection: 'row',
7084
},
85+
largeButton: {
86+
width: 180,
87+
},
88+
smallButton: {
89+
width: 50,
90+
},
7191
icon: {
7292
color: c.white,
7393
fontSize: 30,

source/views/streaming/radio/controller.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import {callPhone} from '../../components/call-phone'
1313
import {Row} from '../../components/layout'
1414
import type {TopLevelViewPropsType} from '../../types'
1515
import {StreamPlayer} from './player'
16-
import type {PlayState, HtmlAudioError} from './types'
16+
import type {PlayState, HtmlAudioError, PlayerTheme} from './types'
1717
import {ActionButton, ShowCalendarButton, CallButton} from './buttons'
1818
import {openUrl} from '../../components/open-url'
1919
import {Viewport} from '../../components/viewport'
20+
import {withTheme} from '@callstack/react-theme-provider'
2021

2122
type Props = TopLevelViewPropsType & {
2223
image: number,
23-
imageBorder: boolean,
2424
playerUrl: string,
2525
stationNumber: string,
2626
title: string,
@@ -31,6 +31,7 @@ type Props = TopLevelViewPropsType & {
3131
embeddedPlayerUrl: string,
3232
streamSourceUrl: string,
3333
},
34+
theme: PlayerTheme,
3435
}
3536

3637
type State = {
@@ -39,7 +40,7 @@ type State = {
3940
uplinkError: ?string,
4041
}
4142

42-
export class RadioControllerView extends React.PureComponent<Props, State> {
43+
class RadioControllerView extends React.Component<Props, State> {
4344
state = {
4445
playState: 'paused',
4546
streamError: null,
@@ -118,7 +119,7 @@ export class RadioControllerView extends React.PureComponent<Props, State> {
118119
}
119120

120121
render() {
121-
const {source, title, stationName, image, imageBorder} = this.props
122+
const {source, title, stationName, image, theme} = this.props
122123
const {uplinkError, streamError, playState} = this.state
123124

124125
const error = uplinkError ? (
@@ -129,12 +130,13 @@ export class RadioControllerView extends React.PureComponent<Props, State> {
129130
</Text>
130131
) : null
131132

133+
let textColor = {color: theme.textColor}
132134
const titleBlock = (
133135
<View style={styles.titleWrapper}>
134-
<Text selectable={true} style={styles.heading}>
136+
<Text selectable={true} style={[styles.heading, textColor]}>
135137
{title}
136138
</Text>
137-
<Text selectable={true} style={styles.subHeading}>
139+
<Text selectable={true} style={[styles.subHeading, textColor]}>
138140
{stationName}
139141
</Text>
140142

@@ -178,7 +180,9 @@ export class RadioControllerView extends React.PureComponent<Props, State> {
178180
const logoSize = {width: logoWidth, height: logoWidth}
179181

180182
const root = [styles.root, sideways && landscape.root]
181-
const logo = [imageBorder && styles.logoBorder, logoSize]
183+
const logoBorderColor = {borderColor: theme.imageBorderColor}
184+
const logoBg = {backgroundColor: theme.imageBackgroundColor}
185+
const logo = [styles.logoBorder, logoSize, logoBorderColor, logoBg]
182186
const logoWrapper = [
183187
styles.logoWrapper,
184188
sideways && landscape.logoWrapper,
@@ -203,6 +207,10 @@ export class RadioControllerView extends React.PureComponent<Props, State> {
203207
}
204208
}
205209

210+
const ThemedRadioControllerView = withTheme(RadioControllerView)
211+
212+
export {ThemedRadioControllerView as RadioControllerView}
213+
206214
const styles = StyleSheet.create({
207215
root: {
208216
flexDirection: 'column',
@@ -223,22 +231,22 @@ const styles = StyleSheet.create({
223231
},
224232
logoBorder: {
225233
borderRadius: 6,
226-
borderColor: c.kstoSecondaryDark,
234+
borderColor: c.black,
227235
borderWidth: 3,
228236
},
229237
titleWrapper: {
230238
alignItems: 'center',
231239
marginBottom: 20,
232240
},
233241
heading: {
234-
color: c.kstoPrimaryDark,
242+
color: c.black,
235243
fontWeight: '600',
236244
fontSize: 28,
237245
textAlign: 'center',
238246
},
239247
subHeading: {
240248
marginTop: 5,
241-
color: c.kstoPrimaryDark,
249+
color: c.black,
242250
fontWeight: '300',
243251
fontSize: 28,
244252
textAlign: 'center',
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// @flow
2+
3+
import * as React from 'react'
4+
import * as c from '../../components/colors'
5+
import {TabBarIcon} from '../../components/tabbar-icon'
6+
import {type TopLevelViewPropsType} from '../../types'
7+
import * as logos from '../../../../images/streaming'
8+
import {RadioControllerView} from './index'
9+
import tinycolor from 'tinycolor2'
10+
import {ThemeProvider} from '@callstack/react-theme-provider'
11+
import {type PlayerTheme} from './types'
12+
13+
let tintColor = '#33348e'
14+
const colors: PlayerTheme = {
15+
tintColor,
16+
buttonTextColor: tinycolor.mostReadable(tintColor, [c.white, c.black]),
17+
textColor: tintColor,
18+
imageBorderColor: tintColor,
19+
imageBackgroundColor: 'transparent',
20+
}
21+
22+
export class KrlxStationView extends React.Component<TopLevelViewPropsType> {
23+
static navigationOptions = {
24+
tabBarLabel: 'KRLX',
25+
tabBarIcon: TabBarIcon('microphone'),
26+
}
27+
28+
render() {
29+
return (
30+
<ThemeProvider theme={colors}>
31+
<RadioControllerView
32+
image={logos.krlx}
33+
navigation={this.props.navigation}
34+
playerUrl="http://live.krlx.org"
35+
scheduleViewName="KRLXScheduleView"
36+
source={{
37+
useEmbeddedPlayer: false,
38+
embeddedPlayerUrl: 'http://live.krlx.org',
39+
streamSourceUrl: 'http://radio.krlx.org/mp3/high_quality',
40+
}}
41+
stationName="88.1 KRLX-FM"
42+
stationNumber="+15072224127"
43+
title="Carleton College Radio"
44+
/>
45+
</ThemeProvider>
46+
)
47+
}
48+
}

0 commit comments

Comments
 (0)