added branding option (#301)

added branding option via '@ <logo>' or '@ <name>' after the CodiMD logo and text.

This was a user can personalize their CodiMD instance

Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
Co-authored-by: Erik Michelson <github@erik.michelson.eu>
Co-authored-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
Philip Molares 2020-07-01 23:20:00 +02:00 committed by GitHub
parent 50b04c8403
commit b23a73ac51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 79 additions and 4 deletions

View file

@ -30,6 +30,7 @@
- Users may now change their display name and password (only email accounts) on the new profile page
- Highlighted code blocks can now use line wrapping and line numbers at once
- Images, videos, and other non-text content is now wider in View Mode
- CodiMD instances can now be branded either with a '@ <custom string>' or '@ <custom logo>' after the CodiMD logo and text
### Changed

BIN
public/acme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -13,6 +13,10 @@
"email": true,
"openid": true
},
"branding": {
"name": "ACME Corp",
"logo": "http://localhost:3000/acme.png"
},
"banner": {
"text": "This is the test banner text",
"timestamp": "2020-05-22T20:46:08.962Z"

View file

@ -1,12 +1,18 @@
export interface BackendConfig {
allowAnonymous: boolean,
authProviders: AuthProvidersState,
branding: BrandingConfig,
banner: BannerConfig,
customAuthNames: CustomAuthNames,
specialLinks: SpecialLinks,
version: BackendVersion,
}
export interface BrandingConfig {
name: string,
logo: string,
}
export interface BannerConfig {
text: string
timestamp: string

View file

@ -0,0 +1,7 @@
.regular-size {
height: 50px;
}
.inline-size {
height: 30px;
}

View file

@ -0,0 +1,32 @@
import React from 'react'
import { useSelector } from 'react-redux'
import { ApplicationState } from '../../../redux'
import { ShowIf } from '../show-if/show-if'
import './branding.scss'
export interface BrandingProps {
inline?: boolean
}
export const Branding: React.FC<BrandingProps> = ({ inline = false }) => {
const branding = useSelector((state: ApplicationState) => state.backendConfig.branding)
const showBranding = branding.name !== '' || branding.logo !== ''
console.log(branding.logo)
return (
<ShowIf condition={showBranding}>
<strong className={`mx-1 ${inline ? 'inline-size' : 'regular-size'}`} >@</strong>
{
branding.logo
? <img
src={branding.logo}
alt={branding.name}
title={branding.name}
className={inline ? 'inline-size' : 'regular-size'}
/>
: branding.name
}
</ShowIf>
)
}

View file

@ -0,0 +1,13 @@
import React, { useEffect } from 'react'
import { useSelector } from 'react-redux'
import { ApplicationState } from '../../../redux'
export const DocumentTitle: React.FC = () => {
const branding = useSelector((state: ApplicationState) => state.backendConfig.branding)
useEffect(() => {
document.title = `CodiMD ${branding.name ? ` @ ${branding.name}` : ''}`
}, [branding])
return null
}

View file

@ -2,6 +2,7 @@ import React from 'react'
import { Button, Nav, Navbar } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { Branding } from '../../common/branding/branding'
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
import { ConnectionIndicator } from './connection-indicator'
import { DarkModeButton } from './dark-mode-button'
@ -15,8 +16,10 @@ const TaskBar: React.FC = () => {
<Navbar bg={'light'}>
<Nav className="mr-auto d-flex align-items-center">
<Navbar.Brand>
<Link to="/intro" className="text-secondary">
<ForkAwesomeIcon icon="file-text"/> CodiMD
<Link to="/intro" className="text-secondary text-decoration-none d-flex align-items-center">
<ForkAwesomeIcon icon="file-text" className={'mr-2'}/>
<span>CodiMD</span>
<Branding inline={true}/>
</Link>
</Navbar.Brand>
<EditorViewMode/>

View file

@ -1,5 +1,6 @@
import React from 'react'
import { Container } from 'react-bootstrap'
import { DocumentTitle } from '../common/document-title/document-title'
import { Footer } from './layout/footer/footer'
import { InfoBanner } from './layout/info-banner'
import { HeaderBar } from './layout/navigation/header-bar/header-bar'
@ -7,6 +8,7 @@ import { HeaderBar } from './layout/navigation/header-bar/header-bar'
export const LandingLayout: React.FC = ({ children }) => {
return (
<Container className="text-white d-flex flex-column mvh-100">
<DocumentTitle/>
<InfoBanner/>
<HeaderBar/>
<div className={'d-flex flex-column justify-content-between flex-fill text-center'}>

View file

@ -1,5 +1,6 @@
import React, { Fragment } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Branding } from '../../../common/branding/branding'
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
import { CoverButtons } from './cover-buttons/cover-buttons'
import { FeatureLinks } from './feature-links'
@ -10,8 +11,10 @@ const Intro: React.FC = () => {
return (
<Fragment>
<h1 dir='auto'>
<ForkAwesomeIcon icon="file-text"/> CodiMD
<h1 dir='auto' className={'align-items-center d-flex justify-content-center'}>
<ForkAwesomeIcon icon="file-text" className={'mr-2'}/>
<span>CodiMD</span>
<Branding/>
</h1>
<p className="lead mb-5">
<Trans i18nKey="app.slogan"/>

View file

@ -17,6 +17,10 @@ export const initialState: BackendConfig = {
email: false,
openid: false
},
branding: {
name: '',
logo: ''
},
banner: {
text: '',
timestamp: ''