Skip to content

Commit

Permalink
Merge branch 'release/1.2.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
ju4n97 committed Apr 17, 2021
2 parents 14e4405 + 6699ec8 commit 51a9766
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 63 deletions.
18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,36 +132,26 @@ Types of pages

You can find the config file in the project root, then you can refer to https://tailwindcss.com/docs/configuration to learn how to make your own adjustments.

- Change light and dark mode colors:

Go to `src/theme/01-base/variables.scss` and change them to your preference.

- Set a default theme (First time load)

Go to `src\app\@core\services\theme\theme.service.ts` and change the following line of code:
Go to `src\app\@core\services\theme\theme.config.ts` and change the following line of code

from operating system preference

```ts
private currentTheme$ = new BehaviorSubject<ThemeList>(
this.currentTheme || ThemeList.System
);
export const defaultBaseTheme = ThemeList.System;
```

to light mode

```ts
private currentTheme$ = new BehaviorSubject<ThemeList>(
this.currentTheme || ThemeList.Light
);
export const defaultBaseTheme = ThemeList.Light;
```

or dark mode

```ts
private currentTheme$ = new BehaviorSubject<ThemeList>(
this.currentTheme || ThemeList.Dark
);
export const defaultBaseTheme = ThemeList.Dark;
```

## 🗑️ Remove features
Expand Down
2 changes: 2 additions & 0 deletions src/app/@core/services/theme/theme.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export enum ThemeList {
Light = 'light',
Dark = 'dark',
}

export const defaultBaseTheme = ThemeList.System;
96 changes: 63 additions & 33 deletions src/app/@core/services/theme/theme.service.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,94 @@
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { Inject, Injectable, OnDestroy } from '@angular/core';
import { getItem, setItem, StorageItem } from '@app/@core/utils';
import { BehaviorSubject } from 'rxjs';
import { ThemeList } from './theme.config';
import { fromEventPattern, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { defaultBaseTheme, ThemeList } from './theme.config';

@Injectable({
providedIn: 'root',
})
export class ThemeService {
private currentTheme$ = new BehaviorSubject<ThemeList>(
this.currentTheme || ThemeList.System,
export class ThemeService implements OnDestroy {
destroy$ = new Subject();

private readonly mediaQuery = window.matchMedia(
'(prefers-color-scheme: dark)',
);

constructor(@Inject(DOCUMENT) private document: Document) {}

get currentTheme(): ThemeList {
get systemTheme(): ThemeList.Light | ThemeList.Dark {
return this.mediaQuery.matches ? ThemeList.Dark : ThemeList.Light;
}

get currentAppTheme(): ThemeList {
return getItem(StorageItem.Theme) as ThemeList;
}

/**
* Makes initial check for system preferences and attach mediaQuery listener
*
*/
init(): void {
if (!this.currentTheme) {
this.listenForMediaQuery();
if (this.currentAppTheme) {
this.setTheme(this.currentAppTheme);
} else if (this.currentAppTheme === ThemeList.System) {
this.setTheme(this.systemTheme);
} else {
this.setTheme(defaultBaseTheme);
}

this.listenForThemeChanges();
this.listenForMediaQueryChanges();
}

changeTheme(theme: ThemeList): void {
this.currentTheme$.next(theme);
}

private listenForMediaQuery(): void {
const colorScheme = window.matchMedia('(prefers-color-scheme: dark)');

colorScheme.addEventListener('change', (e: MediaQueryListEvent) => {
const currentTheme = this.currentTheme;
/**
* Manually changes theme in BehaviorSubject, LocalStorage & HTML element
*
* @param theme new theme
*/
setTheme(theme: ThemeList): void {
this.clearThemes();
setItem(StorageItem.Theme, theme);

if (currentTheme === ThemeList.System) {
const theme = e.matches ? ThemeList.Dark : ThemeList.Light;
this.setTheme(theme);
}
});
}
let bodyClass = theme;

private listenForThemeChanges(): void {
this.currentTheme$.subscribe((theme) => {
this.setTheme(theme);
});
if (theme === ThemeList.System) {
bodyClass = this.systemTheme;
}
this.document.body.classList.add(bodyClass);
}

private setTheme(theme: ThemeList): void {
this.clearThemes();
this.document.body.classList.add(theme);
setItem(StorageItem.Theme, theme);
/**
* Handles system color preference changes
*
*/
private listenForMediaQueryChanges(): void {
fromEventPattern<MediaQueryListEvent>(
this.mediaQuery.addListener.bind(this.mediaQuery),
this.mediaQuery.removeListener.bind(this.mediaQuery),
)
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
// Only applies changes when the current theme is "system"
if (this.currentAppTheme === ThemeList.System) {
this.setTheme(ThemeList.System);
}
});
}

/**
* Clears all themes in ThemeList enum from the HTML element
*
*/
private clearThemes(): void {
for (const theme in ThemeList) {
const key: ThemeList = ThemeList[theme as keyof typeof ThemeList];
this.document.body.classList.remove(key);
}
}

ngOnDestroy(): void {
this.destroy$.complete();
this.destroy$.unsubscribe();
}
}
4 changes: 2 additions & 2 deletions src/app/@core/utils/local-storage.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export enum StorageItem {
Auth = 'auth',
Theme = 'theme',
Auth = 'App/auth',
Theme = 'App/theme',
}

export const getItem = (itemName: StorageItem): unknown | null => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export class AppComponent implements OnInit {
) {}

ngOnInit(): void {
this.isLoggedIn$ = this.authService.isLoggedIn$;
this.seoService.init();
this.themeService.init();
this.isLoggedIn$ = this.authService.isLoggedIn$;
}

onLogout(): void {
Expand Down
12 changes: 1 addition & 11 deletions src/app/components/header/header.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ThemeList, ThemeService } from '@app/@core/services/theme';
import { Path } from '@app/@core/structs';
import { AuthService } from '@app/pages/+auth/_services/auth.service';

Expand All @@ -12,22 +11,13 @@ import { AuthService } from '@app/pages/+auth/_services/auth.service';
})
export class HeaderComponent implements OnInit {
path = Path;
theme = ThemeList;

constructor(
private router: Router,
private themeService: ThemeService,
private authService: AuthService,
) {}
constructor(private router: Router, private authService: AuthService) {}

ngOnInit(): void {}

onClickSignOut(): void {
this.authService.signOut();
this.router.navigate(['/', Path.SignIn]);
}

onClickToggleTheme(theme: ThemeList): void {
this.themeService.changeTheme(theme);
}
}
48 changes: 47 additions & 1 deletion src/app/pages/+home/home.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,56 @@ <h1 i18n class="mb-4">👋 Welcome to Angular Boilerplate.</h1>

<a
[routerLink]="['/', path.App]"
class="inline-block h-12 px-6 py-3 font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-500 focus:ring-4 focus:ring-offset-blue-600 focus:outline-none"
class="inline-block h-12 px-6 py-3 mb-12 font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-500 focus:ring-4 focus:ring-offset-blue-600 focus:outline-none"
type="submit"
>
Go to dashboard
</a>

<h3>Choose a theme</h3>
<div class="flex items-center justify-center space-x-6">
<button
class="inline-block h-12 px-6 py-3 mb-12 font-semibold text-white bg-gray-600 rounded-lg hover:bg-gray-500 focus:ring-4 focus:ring-offset-gray-600 focus:outline-none"
(click)="onClickChangeTheme(theme.System)"
>
System
</button>
<button
class="inline-flex items-center h-12 px-6 py-3 mb-12 font-semibold text-white bg-gray-600 rounded-lg hover:bg-gray-500 focus:ring-4 focus:ring-offset-gray-600 focus:outline-none"
(click)="onClickChangeTheme(theme.Light)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="26"
height="26"
class="mr-3"
>
<path
fill="#FFF"
fill-rule="evenodd"
d="M13 21a1 1 0 011 1v3a1 1 0 11-2 0v-3a1 1 0 011-1zm-5.657-2.343a1 1 0 010 1.414l-2.121 2.121a1 1 0 01-1.414-1.414l2.12-2.121a1 1 0 011.415 0zm12.728 0l2.121 2.121a1 1 0 01-1.414 1.414l-2.121-2.12a1 1 0 011.414-1.415zM13 8a5 5 0 110 10 5 5 0 010-10zm12 4a1 1 0 110 2h-3a1 1 0 110-2h3zM4 12a1 1 0 110 2H1a1 1 0 110-2h3zm18.192-8.192a1 1 0 010 1.414l-2.12 2.121a1 1 0 01-1.415-1.414l2.121-2.121a1 1 0 011.414 0zm-16.97 0l2.121 2.12A1 1 0 015.93 7.344L3.808 5.222a1 1 0 011.414-1.414zM13 0a1 1 0 011 1v3a1 1 0 11-2 0V1a1 1 0 011-1z"
/>
</svg>
Light
</button>
<button
class="inline-flex items-center h-12 px-6 py-3 mb-12 font-semibold text-white bg-gray-600 rounded-lg hover:bg-gray-500 focus:ring-4 focus:ring-offset-gray-600 focus:outline-none"
(click)="onClickChangeTheme(theme.Dark)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="26"
height="26"
class="mr-3"
>
<path
fill="#FFF"
fill-rule="evenodd"
d="M13 0c.81 0 1.603.074 2.373.216C10.593 1.199 7 5.43 7 10.5 7 16.299 11.701 21 17.5 21c2.996 0 5.7-1.255 7.613-3.268C23.22 22.572 18.51 26 13 26 5.82 26 0 20.18 0 13S5.82 0 13 0z"
/>
</svg>
Dark
</button>
</div>
</div>
</div>
8 changes: 7 additions & 1 deletion src/app/pages/+home/home.page.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ThemeList, ThemeService } from '@app/@core/services/theme';
import { Path } from '@core/structs';

@Component({
Expand All @@ -7,8 +8,13 @@ import { Path } from '@core/structs';
})
export class HomePage implements OnInit {
path = Path;
theme = ThemeList;

constructor() {}
constructor(private themeService: ThemeService) {}

ngOnInit(): void {}

onClickChangeTheme(theme: ThemeList): void {
this.themeService.setTheme(theme);
}
}
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
prefix: '',
mode: 'jit',
purge: {
enabled: process.env.NODE_ENV === 'production',
content: ['./src/**/*.{html,scss,ts}'],
},
darkMode: 'class',
Expand Down

1 comment on commit 51a9766

@vercel
Copy link

@vercel vercel bot commented on 51a9766 Apr 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.