Skip to content

Commit

Permalink
[Breaking change] - Renamed Person to StoryGroup
Browse files Browse the repository at this point in the history
  • Loading branch information
Gauravdarkslayer committed Sep 22, 2024
1 parent fea1457 commit c0c5257
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 78 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { NgxStoriesComponent } from 'ngx-stories';
styleUrl: './app.component.css'
})
export class AppComponent {
persons = [
storyGroups = [
{
id: 1,
name: 'John Doe',
Expand All @@ -44,11 +44,11 @@ export class AppComponent {
```

```html
<ngx-stories [persons]="persons"></ngx-stories>
<ngx-stories [storyGroups]="storyGroups"></ngx-stories>
```

## Features
* Dynamic Story Carousel: Display a collection of stories for each person.
* Dynamic Story Carousel: Display a collection of stories for each storyGroup.
* Easy Integration: Simple and straightforward to integrate into your Angular project.
* Story Progress Tracker: Track the progress of each story as the user navigates through the stories.
* Swipe Gestures (Mobile Friendly): Allow users to swipe left or right to navigate through the stories.
Expand Down
6 changes: 3 additions & 3 deletions projects/ngx-stories/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { NgxStoriesComponent } from 'ngx-stories';
styleUrl: './app.component.css'
})
export class AppComponent {
persons = [
storyGroups = [
{
id: 1,
name: 'John Doe',
Expand All @@ -44,11 +44,11 @@ export class AppComponent {
```

```html
<ngx-stories [persons]="persons"></ngx-stories>
<ngx-stories [storyGroups]="storyGroups"></ngx-stories>
```

## Features
* Dynamic Story Carousel: Display a collection of stories for each person.
* Dynamic Story Carousel: Display a collection of stories for each storyGroup.
* Easy Integration: Simple and straightforward to integrate into your Angular project.
* Story Progress Tracker: Track the progress of each story as the user navigates through the stories.
* Swipe Gestures (Mobile Friendly): Allow users to swipe left or right to navigate through the stories.
Expand Down
4 changes: 2 additions & 2 deletions projects/ngx-stories/src/lib/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export interface Story {
content: string,
}

export interface Person {
export interface StoryGroup {
id: number, // unique id
name: string, // name of the person which is to be displayed over story
name: string, // name of the storyGroup which is to be displayed over story
stories: Story[] // array of stories
}
12 changes: 6 additions & 6 deletions projects/ngx-stories/src/lib/ngx-stories.component.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
@for(person of persons; track person.id; let i=$index) {
<div class="story-container" #storyContainer [class.active]="i === currentPersonIndex"
@for(storyGroup of storyGroups; track storyGroup.id; let i=$index) {
<div class="story-container" #storyContainer [class.active]="i === currentStoryGroupIndex"
[class.swipe-left]="isSwipingLeft" [class.swipe-right]="isSwipingRight" (mousedown)="onTouchStart()"
(mouseup)="onRelease()" (touchstart)="onTouchStart()" (touchend)="onRelease()"
(contextmenu)="disableContextMenu($event)">
@for(story of person.stories; track story.id; let z = $index ) {
@for(story of storyGroup.stories; track story.id; let z = $index ) {
<div [class.active]="z === currentStoryIndex" class="story-content">
<div class="story-content-container">
<h5 [style.visibility]="isHolding ? 'hidden' : 'visible'">
{{person.name}}
{{storyGroup.name}}
</h5>
<button (click)="togglePause()">
<img [ngClass]="{ 'pause-icon': isPaused, 'play-icon': !isPaused }" [alt]="isPaused ? 'play-icon' : 'pause-icon'" width="20" height="20">
Expand All @@ -20,13 +20,13 @@ <h5 [style.visibility]="isHolding ? 'hidden' : 'visible'">
}

<div class="progress-bar-container" [style.visibility]="isHolding ? 'hidden' : 'visible'">
@for(story of person.stories; track story.id; let x = $index ) {
@for(story of storyGroup.stories; track story.id; let x = $index ) {
<progress class="progress-bar" [value]="getProgressValue(x)" max="100" [class.active]="x===currentStoryIndex">
</progress>
<div style="width: 2vw;"></div>
}
</div>
@if(!(currentPersonIndex === 0 && currentStoryIndex === 0) ) {
@if(!(currentStoryGroupIndex === 0 && currentStoryIndex === 0) ) {
<button class="prev" (click)="prevStory()">Previous</button>
}
<button class="next" style="right: 1%;" (click)="nextStory()">Next</button>
Expand Down
14 changes: 7 additions & 7 deletions projects/ngx-stories/src/lib/ngx-stories.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgxStoriesComponent } from './ngx-stories.component';
import { Person } from './interfaces/interfaces';
import { StoryGroup } from './interfaces/interfaces';

describe('NgxStoriesComponent', () => {
let component: NgxStoriesComponent;
Expand All @@ -20,8 +20,8 @@ describe('NgxStoriesComponent', () => {
expect(1).toBeTruthy();
});

it('should accept persons input and display stories', () => {
const mockPersons: Person[] = [
it('should accept storyGroups input and display stories', () => {
const mockStoryGroups: StoryGroup[] = [
{
id: 1,
name: 'Gaurav',
Expand All @@ -32,11 +32,11 @@ describe('NgxStoriesComponent', () => {
},
];

component.persons = mockPersons;
component.storyGroups = mockStoryGroups;
fixture.detectChanges();

expect(component.persons.length).toBe(1);
expect(component.persons[0].name).toBe('Gaurav');
expect(component.persons[0].stories.length).toBe(2);
expect(component.storyGroups.length).toBe(1);
expect(component.storyGroups[0].name).toBe('Gaurav');
expect(component.storyGroups[0].stories.length).toBe(2);
});
});
38 changes: 19 additions & 19 deletions projects/ngx-stories/src/lib/ngx-stories.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, QueryList, ViewChildren } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HammerModule } from '@angular/platform-browser';
import { Person } from '../lib/interfaces/interfaces';
import { StoryGroup } from '../lib/interfaces/interfaces';
import "hammerjs";
import { CommonModule } from '@angular/common';
import { NgxStoriesService } from './ngx-stories.service';
Expand All @@ -16,16 +16,16 @@ import { NgxStoriesService } from './ngx-stories.service';
export class NgxStoriesComponent implements AfterViewInit {
title = 'ngx-stories';

// Input property to accept the list of persons and their stories
@Input({ required: true }) persons: Person[] = [];
// Input property to accept the list of storyGroup and their stories
@Input({ required: true }) storyGroups: StoryGroup[] = [];

// Output events to handle end of stories, exit, and swipe-up gesture
@Output() triggerOnEnd = new EventEmitter<void>();
@Output() triggerOnExit = new EventEmitter<void>();
@Output() triggerOnSwipeUp = new EventEmitter<void>();

currentStoryIndex: number = 0;
currentPersonIndex: number = 0;
currentStoryGroupIndex: number = 0;
progressWidth: number = 0;
intervalId: any; // Interval for story progress
isTransitioning = false; // Prevents multiple transitions at once
Expand Down Expand Up @@ -79,18 +79,18 @@ export class NgxStoriesComponent implements AfterViewInit {
if (direction === 'left') {
this.isSwipingLeft = true;
setTimeout(() => {
if (this.currentPersonIndex === this.persons.length - 1) {
let stories = this.persons.find((person, index) => index === this.currentPersonIndex)?.stories;
if (this.currentStoryGroupIndex === this.storyGroups.length - 1) {
let stories = this.storyGroups.find((storyGroup, index) => index === this.currentStoryGroupIndex)?.stories;
this.currentStoryIndex = Number(stories?.length) - 1;
if (this.checkEnd()) return;
}
this.nextPersonStory();
this.nextStoryGroup();
this.resetSwipe();
}, 600); // Match the animation duration
} else if (direction === 'right') {
this.isSwipingRight = true;
setTimeout(() => {
this.prevPersonStory();
this.prevStoryGroup();
this.resetSwipe();
}, 600); // Match the animation duration
} else if (direction === 'down') {
Expand All @@ -116,8 +116,8 @@ export class NgxStoriesComponent implements AfterViewInit {
}

// Using the service to determine the next story
const { personIndex, storyIndex } = this.storyService.nextStory(this.persons, this.currentPersonIndex, this.currentStoryIndex);
this.currentPersonIndex = personIndex;
const { storyGroupIndex, storyIndex } = this.storyService.nextStory(this.storyGroups, this.currentStoryGroupIndex, this.currentStoryIndex);
this.currentStoryGroupIndex = storyGroupIndex;
this.currentStoryIndex = storyIndex;

this.progressWidth = 0;
Expand All @@ -133,8 +133,8 @@ export class NgxStoriesComponent implements AfterViewInit {
clearInterval(this.intervalId);

// Using the service to determine the previous story
const { personIndex, storyIndex } = this.storyService.prevStory(this.persons, this.currentPersonIndex, this.currentStoryIndex);
this.currentPersonIndex = personIndex;
const { storyGroupIndex, storyIndex } = this.storyService.prevStory(this.storyGroups, this.currentStoryGroupIndex, this.currentStoryIndex);
this.currentStoryGroupIndex = storyGroupIndex;
this.currentStoryIndex = storyIndex;

this.progressWidth = 0;
Expand All @@ -145,10 +145,10 @@ export class NgxStoriesComponent implements AfterViewInit {
}


nextPersonStory() {
nextStoryGroup() {
if (this.isTransitioning) return;
this.isTransitioning = true;
this.currentPersonIndex = (this.currentPersonIndex + 1) % this.persons.length;
this.currentStoryGroupIndex = (this.currentStoryGroupIndex + 1) % this.storyGroups.length;
if (this.checkEnd()) return;
this.currentStoryIndex = 0;
clearInterval(this.intervalId);
Expand All @@ -159,13 +159,13 @@ export class NgxStoriesComponent implements AfterViewInit {
}, 500); // Match this timeout with the CSS transition duration
}

prevPersonStory() {
prevStoryGroup() {
if (this.isTransitioning) return;
this.isTransitioning = true;
this.currentStoryIndex = 0;
clearInterval(this.intervalId);
if (this.currentPersonIndex !== 0 && this.persons.length > this.currentPersonIndex) {
this.currentPersonIndex--;
if (this.currentStoryGroupIndex !== 0 && this.storyGroups.length > this.currentStoryGroupIndex) {
this.currentStoryGroupIndex--;
}
this.progressWidth = 0;
setTimeout(() => {
Expand All @@ -175,8 +175,8 @@ export class NgxStoriesComponent implements AfterViewInit {
}

checkEnd(): boolean {
let stories = this.persons.find((person, index) => index === this.currentPersonIndex)?.stories;
if (this.currentStoryIndex === Number(stories?.length) - 1 && this.currentPersonIndex === this.persons.length - 1) {
let stories = this.storyGroups.find((storyGroup, index) => index === this.currentStoryGroupIndex)?.stories;
if (this.currentStoryIndex === Number(stories?.length) - 1 && this.currentStoryGroupIndex === this.storyGroups.length - 1) {
this.onEnd();
return true;
}
Expand Down
40 changes: 20 additions & 20 deletions projects/ngx-stories/src/lib/ngx-stories.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TestBed } from '@angular/core/testing';

import { NgxStoriesService } from './ngx-stories.service';
import { Person } from './interfaces/interfaces';
import { StoryGroup } from './interfaces/interfaces';

describe('NgxStoriesService', () => {
let service: NgxStoriesService;
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('NgxStoriesService', () => {
});

describe('nextStory', () => {
const persons: Person[] = [
const storyGroups: StoryGroup[] = [
{
id: 1,
name: 'John Doe',
Expand All @@ -66,23 +66,23 @@ describe('NgxStoriesService', () => {
}
];

it('should move to the next story within the same person', () => {
const result = service.nextStory(persons, 0, 0); // Start at person 0, story 0
expect(result.personIndex).toBe(0);
it('should move to the next story within the same storyGroup', () => {
const result = service.nextStory(storyGroups, 0, 0); // Start at storyGroup 0, story 0
expect(result.storyGroupIndex).toBe(0);
expect(result.storyIndex).toBe(1);
});

it('should move to the next person if current story is the last one', () => {
const result = service.nextStory(persons, 0, 2); // Start at person 0, story 2 (last story)
expect(result.personIndex).toBe(1); // Moved to next person
expect(result.storyIndex).toBe(0); // First story of the next person
it('should move to the next storyGroup if current story is the last one', () => {
const result = service.nextStory(storyGroups, 0, 2); // Start at storyGroup 0, story 2 (last story)
expect(result.storyGroupIndex).toBe(1); // Moved to next storyGroup
expect(result.storyIndex).toBe(0); // First story of the next storyGroup
});

});


describe('prevStory', () => {
const persons: Person[] = [
const storyGroups: StoryGroup[] = [
{
id: 1,
name: 'John Doe',
Expand All @@ -102,21 +102,21 @@ describe('NgxStoriesService', () => {
}
];

it('should move to the previous story within the same person', () => {
const result = service.prevStory(persons, 0, 2); // Start at person 0, story 2
expect(result.personIndex).toBe(0);
it('should move to the previous story within the same storyGroup', () => {
const result = service.prevStory(storyGroups, 0, 2); // Start at storyGroup 0, story 2
expect(result.storyGroupIndex).toBe(0);
expect(result.storyIndex).toBe(1);
});

it('should move to the previous person if current story is the first one', () => {
const result = service.prevStory(persons, 1, 0); // Start at person 1, story 0
expect(result.personIndex).toBe(0); // Moved to previous person
expect(result.storyIndex).toBe(2); // Last story of the previous person
it('should move to the previous storyGroup if current story is the first one', () => {
const result = service.prevStory(storyGroups, 1, 0); // Start at storyGroup 1, story 0
expect(result.storyGroupIndex).toBe(0); // Moved to previous storyGroup
expect(result.storyIndex).toBe(2); // Last story of the previous storyGroup
});

it('should do nothing if on the first story of the first person', () => {
const result = service.prevStory(persons, 0, 0); // First story of the first person
expect(result.personIndex).toBe(0);
it('should do nothing if on the first story of the first storyGroup', () => {
const result = service.prevStory(storyGroups, 0, 0); // First story of the first storyGroup
expect(result.storyGroupIndex).toBe(0);
expect(result.storyIndex).toBe(0); // Remains at the first story
});
});
Expand Down
30 changes: 15 additions & 15 deletions projects/ngx-stories/src/lib/ngx-stories.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from "@angular/core";
import { Person } from "./interfaces/interfaces";
import { StoryGroup } from "./interfaces/interfaces";
@Injectable({
providedIn: 'root',
})
Expand All @@ -17,32 +17,32 @@ export class NgxStoriesService {
clearInterval(intervalId);
}

nextStory(persons: Person[], currentPersonIndex: number, currentStoryIndex: number): { personIndex: number, storyIndex: number } {
let stories = persons[currentPersonIndex]?.stories;
nextStory(storyGroups: StoryGroup[], currentStoryGroupIndex: number, currentStoryIndex: number): { storyGroupIndex: number, storyIndex: number } {
let stories = storyGroups[currentStoryGroupIndex]?.stories;
if (currentStoryIndex === stories.length - 1) {
// Move to the next person if the current story index is the last
currentPersonIndex = (currentPersonIndex + 1) % persons.length;
// Move to the next storyGroup if the current story index is the last
currentStoryGroupIndex = (currentStoryGroupIndex + 1) % storyGroups.length;
currentStoryIndex = 0;
} else {
// Otherwise, just move to the next story within the same person
// Otherwise, just move to the next story within the same storyGroup
currentStoryIndex++;
}
return { personIndex: currentPersonIndex, storyIndex: currentStoryIndex };
return { storyGroupIndex: currentStoryGroupIndex, storyIndex: currentStoryIndex };
}

prevStory(persons: any[], currentPersonIndex: number, currentStoryIndex: number): { personIndex: number, storyIndex: number } {
let stories = persons[currentPersonIndex]?.stories;
prevStory(storyGroups: StoryGroup[], currentStoryGroupIndex: number, currentStoryIndex: number): { storyGroupIndex: number, storyIndex: number } {
let stories = storyGroups[currentStoryGroupIndex]?.stories;
if (currentStoryIndex === 0) {
// Move to the previous person if the current story index is 0
if (currentPersonIndex > 0) {
currentPersonIndex--;
stories = persons[currentPersonIndex]?.stories;
// Move to the previous storyGroup if the current story index is 0
if (currentStoryGroupIndex > 0) {
currentStoryGroupIndex--;
stories = storyGroups[currentStoryGroupIndex]?.stories;
currentStoryIndex = stories.length - 1;
}
} else {
// Otherwise, just move to the previous story within the same person
// Otherwise, just move to the previous story within the same storyGroup
currentStoryIndex--;
}
return { personIndex: currentPersonIndex, storyIndex: currentStoryIndex };
return { storyGroupIndex: currentStoryGroupIndex, storyIndex: currentStoryIndex };
}
}
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ <h1>Ngx-Stories Demo</h1>


<ngx-stories
[persons]="persons"
[storyGroups]="storyGroups"
(triggerOnEnd)="triggerOnEnd()"
(triggerOnExit)="triggerOnExit()"
></ngx-stories>
Loading

0 comments on commit c0c5257

Please sign in to comment.