Skip to content

Commit

Permalink
Animations update
Browse files Browse the repository at this point in the history
  • Loading branch information
logashoff committed May 26, 2024
1 parent fea82ce commit de332e2
Show file tree
Hide file tree
Showing 31 changed files with 337 additions and 194 deletions.
2 changes: 1 addition & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"minify": true,
"inlineCritical": false
},
"fonts": false
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "new-collections",
"description": "Browser extension to save and restore tabs",
"version": "1.5.0",
"version": "1.6.0",
"scripts": {
"ng": "ng",
"build": "ng build --configuration production --output-hashing none",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Routes } from '@angular/router';
import { HomeService } from './services/index';

export const appRoutes: Routes = [
{
path: 'new-tab',
providers: [HomeService],
loadComponent: () => import('./components/new-tab/new-tab.component').then((m) => m.NewTabComponent),
loadChildren: () => import('./components/new-tab/new-tab.routes').then((m) => m.newTabRoutes),
},
Expand Down
11 changes: 9 additions & 2 deletions src/app/components/groups/groups.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,19 @@
<mat-divider />

@if (group.tabs$ | async; as tabs) {
<app-tab-list cdkDropList (cdkDropListDropped)="drop($event, tabs)">
@for (tab of tabs; track tab) {
<app-tab-list cdkDropList
(cdkDropListDropped)="drop($event, tabs)">
@for (tab of tabs; track tab.id) {
<app-list-item
cdkDrag
[@listItemAnimation]
[cdkDragDisabled]="dragDisabled"
[tab]="tab"
[tabs]="timelineTabs$ | async"
[openTabs]="openTabs$ | async"
[target]="isPopup ? '_blank' : '_self'"
(modified)="editTab(tab)"
(deleted)="deleteTab(tab)"
[focused]="(activeGroupId$ | async) === group.id && (activeTabId$ | async) === tab.id" />
}
</app-tab-list>
Expand Down
23 changes: 22 additions & 1 deletion src/app/components/groups/groups.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ import { MatIconModule } from '@angular/material/icon';
import { BehaviorSubject, Observable, map, shareReplay } from 'rxjs';
import { IsReadOnlyGroupPipe } from '../../pipes/index';
import { NavService, SettingsService, TabService } from '../../services/index';
import { BrowserTabs, GroupExpanded, TabGroup, TabGroups, TabsByHostname } from '../../utils/index';
import {
BrowserTab,
BrowserTabs,
GroupExpanded,
TabGroup,
TabGroups,
TabsByHostname,
listItemAnimation,
} from '../../utils/index';
import { GroupControlsComponent } from '../group-controls/group-controls.component';
import { ListItemComponent } from '../list-item/list-item.component';
import { PanelHeaderComponent } from '../panel-header/panel-header.component';
Expand All @@ -25,6 +33,7 @@ import { RippleComponent } from '../ripple/ripple.component';
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
animations: [listItemAnimation],
imports: [
CommonModule,
DragDropModule,
Expand Down Expand Up @@ -92,6 +101,10 @@ export class GroupsComponent {

readonly isNaN = isNaN;

readonly openTabs$ = this.tabService.openTabChanges$.pipe(shareReplay(1));
readonly timelineTabs$ = this.tabService.tabs$.pipe(shareReplay(1));
readonly isPopup = this.navService.isPopup;

constructor(
private readonly navService: NavService,
private readonly tabService: TabService,
Expand Down Expand Up @@ -127,4 +140,12 @@ export class GroupsComponent {
moveItemInArray(tabs, event.previousIndex, event.currentIndex);
this.tabService.save();
}

async editTab(tab: BrowserTab) {
await this.tabService.updateTab(tab);
}

async deleteTab(tab: BrowserTab) {
await this.tabService.removeTab(tab);
}
}
4 changes: 2 additions & 2 deletions src/app/components/list-item/list-item.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<div class="subtitle-container">
@if (hasLabels$ | async) {
<span class="label-container">
@if (openTabs$ | async) {
@if (openTabsCount$ | async) {
<app-label color="primary">
{{ 'openTabs' | translate: { count: openTabs$ | async } }}
{{ 'openTabs' | translate: { count: openTabsCount$ | async } }}
</app-label>
}

Expand Down
110 changes: 53 additions & 57 deletions src/app/components/list-item/list-item.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { animate, state, style, transition, trigger } from '@angular/animations';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
HostBinding,
Input,
OnInit,
Output,
ViewEncapsulation,
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { EXPANSION_PANEL_ANIMATION_TIMING } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { BehaviorSubject, Observable, combineLatest, map, shareReplay, switchMap } from 'rxjs';
import { BehaviorSubject, Observable, combineLatest, filter, map, shareReplay, switchMap } from 'rxjs';
import { StopPropagationDirective } from '../../directives/index';
import { FaviconPipe } from '../../pipes/index';
import { NavService, TabService } from '../../services/index';
import { BrowserTab, BrowserTabs, TabDelete, Tabs } from '../../utils/index';
import { BrowserTab, BrowserTabs, Tabs } from '../../utils/index';
import { ChipComponent } from '../chip/chip.component';
import { LabelComponent } from '../label/label.component';
import { RippleComponent } from '../ripple/ripple.component';
Expand Down Expand Up @@ -47,34 +44,29 @@ import { RippleComponent } from '../ripple/ripple.component';
StopPropagationDirective,
TranslateModule,
],
animations: [
trigger('fadeAnimation', [
state(
'void',
style({
transform: 'translateY(20%)',
opacity: 0,
})
),
transition('void => *', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
]),
],
})
export class ListItemComponent {
private readonly tab$ = new BehaviorSubject<BrowserTab>(null);
export class ListItemComponent implements OnInit {
readonly #tab$ = new BehaviorSubject<BrowserTab>(null);

@HostBinding('@fadeAnimation')
@Input()
set tab(value: BrowserTab) {
this.tab$.next(value);
this.#tab$.next(value);
}

get tab(): BrowserTab {
return this.tab$.value;
return this.#tab$.value;
}

get savedTabs$(): Observable<BrowserTabs> {
return this.tabService?.tabs$.pipe(shareReplay(1));
readonly #tabs$ = new BehaviorSubject<BrowserTabs>(null);

@Input() set tabs(value: BrowserTabs) {
this.#tabs$.next(value);
}

readonly #openTabs$ = new BehaviorSubject<Tabs>(null);

@Input() set openTabs(value: Tabs) {
this.#openTabs$.next(value);
}

/**
Expand All @@ -85,16 +77,26 @@ export class ListItemComponent {
/**
* Disables item menu
*/
readonly notReadOnly$: Observable<boolean> = this.tab$.pipe(
switchMap((tab) => this.savedTabs$.pipe(map((tabs) => tabs.some((t) => t.id === tab.id)))),
readonly notReadOnly$: Observable<boolean> = this.#tab$.pipe(
switchMap((tab) =>
this.#tabs$.pipe(
filter((tabs) => tabs?.length > 0),
map((tabs) => tabs.some((t) => t.id === tab.id))
)
),
shareReplay(1)
);

/**
* Indicates if list item is part of timeline.
*/
readonly inTimeline$: Observable<boolean> = this.tab$.pipe(
switchMap((tab) => this.savedTabs$.pipe(map((tabs) => tabs.some((t) => t.id === tab.id)))),
readonly inTimeline$: Observable<boolean> = this.#tab$.pipe(
switchMap((tab) =>
this.#tabs$.pipe(
filter((tabs) => tabs?.length > 0),
map((tabs) => tabs.some((t) => t.id === tab.id))
)
),
shareReplay(1)
);

Expand All @@ -106,38 +108,39 @@ export class ListItemComponent {
/**
* Dispatches event when Delete menu item is clicked
*/
@Output() readonly deleted = new EventEmitter<TabDelete>();
@Output() readonly deleted = new EventEmitter<BrowserTab>();

/**
* Scroll this list item into view
*/
@Output() readonly find = new EventEmitter<BrowserTab>();

/**
* Target where URL will be opened when list item is clicked
* Target window to open URL
*/
get target(): string {
return this.nav.isPopup ? '_blank' : '_self';
}
@Input() target: '_blank' | '_self' = '_self';

/**
* Indicates how many tabs are currently open that match this tab's URL
*/
readonly openTabs$: Observable<number>;

readonly dupTabs$: Observable<number> = this.tab$.pipe(
switchMap((tab) => this.savedTabs$.pipe(map((tabs) => tabs.filter((t) => t.url === tab.url)?.length)))
openTabsCount$: Observable<number>;

readonly dupTabs$: Observable<number> = this.#tab$.pipe(
switchMap((tab) =>
this.#tabs$.pipe(
filter((tabs) => tabs?.length > 0),
map((tabs) => tabs.filter((t) => t.url === tab.url)?.length)
)
),
shareReplay(1)
);

readonly activeTab$: Observable<boolean>;
readonly pinnedTab$: Observable<boolean>;
readonly hasLabels$: Observable<boolean>;
activeTab$: Observable<boolean>;
pinnedTab$: Observable<boolean>;
hasLabels$: Observable<boolean>;

constructor(
private tabService: TabService,
private nav: NavService
) {
const openTabs$: Observable<Tabs> = combineLatest([this.tab$, this.tabService.tabChanges$]).pipe(
ngOnInit() {
const openTabs$: Observable<Tabs> = combineLatest([this.#tab$, this.#openTabs$]).pipe(
map(([tab, tabs]) => tabs?.filter((t) => t.url === tab.url)),
shareReplay(1)
);
Expand All @@ -152,12 +155,12 @@ export class ListItemComponent {
shareReplay(1)
);

this.openTabs$ = openTabs$.pipe(
this.openTabsCount$ = openTabs$.pipe(
map((tabs) => tabs?.length),
shareReplay(1)
);

this.hasLabels$ = combineLatest([this.activeTab$, this.pinnedTab$, this.openTabs$, this.dupTabs$]).pipe(
this.hasLabels$ = combineLatest([this.activeTab$, this.pinnedTab$, this.openTabsCount$, this.dupTabs$]).pipe(
map(([active, pinned, openTabs, dupTabs]) => active || pinned || openTabs > 0 || dupTabs > 1),
shareReplay(1)
);
Expand All @@ -167,20 +170,13 @@ export class ListItemComponent {
* Opens dialog to edit specified tab.
*/
async editClick() {
const updatedTab = await this.tabService.updateTab(this.tab);

this.modified.emit(updatedTab);
this.modified.emit(this.tab);
}

/**
* Handles delete menu item click
*/
async deleteClick() {
const messageRef = await this.tabService.removeTab(this.tab);

this.deleted.emit({
deletedTab: this.tab,
revertDelete: messageRef,
});
this.deleted.emit(this.tab);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { TimelineElementComponent } from '../timeline-element/timeline-element.c
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, EmptyComponent, GroupsComponent, TimelineElementComponent],
providers: [HomeService],
})
export class NewTabContentComponent {
readonly defaultActions: CollectionActions = [
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/new-tab-search/new-tab-search.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { flatMap } from 'lodash-es';
import { Observable, map, shareReplay } from 'rxjs';
import { HomeService, NavService, TabService } from '../../services/index';
Expand All @@ -9,8 +9,8 @@ import { SearchComponent } from '../search/search.component';
@Component({
selector: 'app-new-tab-search',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, SearchComponent],
providers: [HomeService],
templateUrl: './new-tab-search.component.html',
styleUrl: './new-tab-search.component.scss',
})
Expand Down
8 changes: 3 additions & 5 deletions src/app/components/new-tab/new-tab.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
@if (topSites$ | async) {
<app-top-sites
class="top-sites"
[ngClass]="{ hidden: hideTopSites$ | async }"
@if ((hideTopSites$ | async) === false) {
<app-top-sites class="top-sites"
[topSites]="topSites$ | async" />
}
<app-search-form
Expand All @@ -11,6 +9,6 @@
(activated)="navigate('search')"
(canceled)="navigate('main')"
/>
<section class="content">
<section class="content" [@routeAnimations]="urlChanges$ | async">
<router-outlet />
</section>
5 changes: 0 additions & 5 deletions src/app/components/new-tab/new-tab.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ app-new-tab {

.top-sites {
overflow: hidden;

&.hidden {
visibility: hidden;
height: 0;
}
}

.content,
Expand Down
Loading

0 comments on commit de332e2

Please sign in to comment.