diff --git a/src/app/effects/api-search.effects.ts b/src/app/effects/api-search.effects.ts index 2a110c7ad..890d4fcd6 100644 --- a/src/app/effects/api-search.effects.ts +++ b/src/app/effects/api-search.effects.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { Location } from '@angular/common'; -import { Title } from '@angular/platform-browser'; import { Store, Action } from '@ngrx/store'; import { Effect, Actions, ofType } from '@ngrx/effects'; import { Observable, of } from 'rxjs'; @@ -206,31 +205,12 @@ export class ApiSearchEffects { }) ); - @Effect({ dispatch: false }) - resetTitleAfterWallSearchSuccess$: Observable = this.actions$ - .pipe( - ofType( - apiAction.ActionTypes.WALL_SEARCH_COMPLETE_SUCCESS, - apiAction.ActionTypes.WALL_SEARCH_COMPLETE_FAIL - ), - withLatestFrom(this.store$), - map(([action, state]) => { - const displayString = state.mediaWallQuery.query.displayString; - let title = `${displayString} - Loklak Media Wall`; - if (action.type === apiAction.ActionTypes.WALL_SEARCH_COMPLETE_FAIL) { - title += ' - No Results'; - } - this.titleService.setTitle(title); - }) - ); - constructor( private store$: Store, private actions$: Actions, private apiSearchService: SearchService, private pushService: PushService, - private location: Location, - private titleService: Title + private location: Location ) { } } diff --git a/src/app/feed/feed.component.html b/src/app/feed/feed.component.html index 3c01eae5f..08b6d4c30 100644 --- a/src/app/feed/feed.component.html +++ b/src/app/feed/feed.component.html @@ -29,9 +29,9 @@ [apiResponseTags]="(apiResponseTags$ | async)">
- + [ApiResponseResult]="(apiResponseResults$ | async)">
-
- -
{{item[0]}} - {{item[1]}} + {{item[1].length}} - @{{item[0]}} + @{{item[1]}} @@ -25,10 +25,10 @@

Top Hashtags

-
{{item[1]}}
+
{{item[1][0].length}}
- #{{item[0]}} + #{{item[1][0]}} @@ -43,10 +43,10 @@

Top Mentions

- {{item[1]}} + {{item[1][0].length}} - @{{item[0]}} + @{{item[1][0]}} diff --git a/src/app/feed/info-box/info-box.component.ts b/src/app/feed/info-box/info-box.component.ts index 091afcc8e..e5f2743fb 100644 --- a/src/app/feed/info-box/info-box.component.ts +++ b/src/app/feed/info-box/info-box.component.ts @@ -1,9 +1,8 @@ +import { ApiResponseResult } from './../../models/api-response'; import { Component, OnInit, OnChanges, Input } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import * as fromRoot from '../../reducers'; -import * as apiAction from '../../actions/api'; -import { ApiResponseAggregations } from '../../models/api-response'; import { Query } from '../../models'; @Component({ @@ -13,7 +12,7 @@ import { Query } from '../../models'; }) export class InfoBoxComponent implements OnInit, OnChanges { @Input() public query: Query; - @Input() public apiResponseAggregations: ApiResponseAggregations; + @Input() public ApiResponseResult: ApiResponseResult[]; public inviewporttwitters: Observable; public inviewportmentions: Observable; public areTopHashtagsAvailable: boolean; @@ -40,18 +39,15 @@ export class InfoBoxComponent implements OnInit, OnChanges { ngOnInit() { } ngOnChanges() { - this.sortHashtags(this.apiResponseAggregations); - this.sortTwiterers(this.apiResponseAggregations); - this.sortMentions(this.apiResponseAggregations); - this.getChartData(this.apiResponseAggregations); + this.parseApiResponseData(); } sortHashtags(statistics) { let sortable = []; /* A check for both the data and the individual objects is necessary, also if the data is not empty*/ - if ((statistics && statistics.hashtags !== undefined) && Object.keys(statistics.hashtags).length !== 0) { - for (const s in statistics.hashtags) { + if (statistics !== undefined && statistics.length !== 0) { + for (const s in statistics) { if (s) { - sortable.push([s, statistics.hashtags[s]]); + sortable.push([s, statistics[s]]); } } sortable.sort(function (a, b) { @@ -70,10 +66,11 @@ export class InfoBoxComponent implements OnInit, OnChanges { } sortTwiterers(statistics) { let sortable = []; - if ((statistics && statistics.screen_name) !== undefined && (Object.keys(statistics.screen_name).length) !== 0) { - for (const s in statistics.screen_name) { + statistics = statistics.filter((el, i, a) => i === a.indexOf(el)); + if (statistics !== undefined && statistics.length !== 0) { + for (const s in statistics) { if (s) { - sortable.push([s, statistics.screen_name[s]]); + sortable.push([s, statistics[s]]); } } sortable.sort(function (a, b) { @@ -92,10 +89,11 @@ export class InfoBoxComponent implements OnInit, OnChanges { } sortMentions(statistics) { let sortable = []; - if ((statistics && statistics.mentions) !== undefined && (Object.keys(statistics.mentions).length !== 0)) { - for (const s in statistics.mentions) { + statistics = statistics.filter(([el], i, a) => i === a.indexOf(el)); + if (statistics !== undefined && statistics.length !== 0) { + for (const s in statistics) { if (s) { - sortable.push([s, statistics.mentions[s]]); + sortable.push([s, statistics[s]]); } } sortable.sort(function (a, b) { @@ -123,17 +121,46 @@ export class InfoBoxComponent implements OnInit, OnChanges { this.inviewportmentions = event.value; } } + + parseApiResponseData() { + const tagStrings = []; + const screenStrings = []; + const mentionStrings = []; + const createdStrings = []; + for ( let i = 0; i < this.ApiResponseResult.length; i++) { + if (this.ApiResponseResult[i]['hashtags'].length !== 0) { + tagStrings.push(this.ApiResponseResult[i]['hashtags']); + } + if (this.ApiResponseResult[i]['screen_name'].length !== 0) { + screenStrings.push(this.ApiResponseResult[i]['screen_name']); + } + if (this.ApiResponseResult[i]['mentions'].length !== 0) { + mentionStrings.push(this.ApiResponseResult[i]['mentions']); + } + if (this.ApiResponseResult[i]['created_at'].length !== 0) { + createdStrings.push(this.ApiResponseResult[i]['created_at']); + } + } + this.sortHashtags(tagStrings); + this.sortTwiterers(screenStrings); + this.sortMentions(mentionStrings); + this.getChartData(createdStrings); + } + getChartData(statistics) { - if ((statistics && statistics.created_at) !== undefined && (Object.keys(statistics.created_at).length !== 0)) { + + for (let i = 0; i < statistics.length; i++) { + statistics[i] = JSON.stringify(statistics[i]).substring(15, statistics.length); + } + const count = {}; + statistics.forEach(function(i) { count[i] = (count[i] || 0) + 1; }); + if (statistics !== undefined && statistics.length !== 0) { const data = []; const labels = []; - const chosen_attr = statistics.created_at; - - - for (const property in chosen_attr) { - if (chosen_attr.hasOwnProperty(property)) { - labels.push(property); - data.push(chosen_attr[property]); + for (const key in count) { + if (count.hasOwnProperty(key)) { + data.push(count[key]); + labels.push(key); } } diff --git a/src/app/feed/user-info-box/user-info-box.component.html b/src/app/feed/user-info-box/user-info-box.component.html index 002348b92..635116d64 100644 --- a/src/app/feed/user-info-box/user-info-box.component.html +++ b/src/app/feed/user-info-box/user-info-box.component.html @@ -16,7 +16,7 @@

{{ apiResponseUser.name }}

@{{ apiResponseUser.screen_name }}
-
+
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 9772deba5..a5c02586e 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -10,7 +10,7 @@

loklak Search!

+ (keypress)="onEnter($event)" (focus)="inputFocused=true" (focusout)="inputFocused=false"/> diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index fa190ce5e..5bf1c0a81 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -132,7 +132,7 @@ describe('Component: Home', () => { const component = fixture.debugElement.componentInstance; const compiled = fixture.debugElement.nativeElement; - const value = 'a'; + const value = 'since:day'; const query$ = component.store.select(fromRoot.getQuery); let displayString: string; diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index f7c138639..cd0977614 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -47,8 +47,6 @@ export class HomeComponent implements OnInit, OnDestroy, AfterContentChecked { this.store.dispatch(new titleAction.SetTitleAction('Loklak Search - ' + 'Distributed Open Source Search for Twitter and Social Media with Peer to Peer Technology')); this.focusTextbox(); - this.setupSearchField(); - this.getDataFromStore(); this.getTopHashtags(); } @@ -61,21 +59,22 @@ export class HomeComponent implements OnInit, OnDestroy, AfterContentChecked { /** * Setup for the `FormControl` of the search field. - * Subscribes to the valueChange Observable, and dispatches `SearchAction` - * when value changes along with redirecting to the `FeedPage`. + * gets the input value when user clicks Enter(13) and dispatches `SearchAction` + * when the query is not empty or containing spaces. + * If query is non empty and user clicks enter, then user is redirected to the `FeedPage`. */ - private setupSearchField() { - this.__subscriptions__.push( - this._queryControl.valueChanges - .subscribe((value) => { - this.store.dispatch(new queryAction.RelocationAfterQuerySetAction()); - this.store.dispatch(new suggestAction.SuggestAction(value)); - this.store.dispatch(new queryAction.InputValueChangeAction(value)); - this.router.navigate([`/search`], { queryParams: { query: value }, skipLocationChange: true } ); - this.store.dispatch(new titleAction.SetTitleAction(value + ' - Loklak Search')); - } - ) - ); + + onEnter(event: any) { + if (event.which === 13) { + if (this._queryControl.value.trim() !== '') { + this.store.dispatch(new queryAction.RelocationAfterQuerySetAction()); + this.store.dispatch(new suggestAction.SuggestAction(this._queryControl.value.trim())); + this.store.dispatch(new queryAction.InputValueChangeAction(this._queryControl.value.trim())); + this.router.navigate([`/search`], { queryParams: { query: this._queryControl.value.trim() }, skipLocationChange: true } ); + this.store.dispatch(new titleAction.SetTitleAction(this._queryControl.value.trim() + ' - Loklak Search')); + this.getDataFromStore(); + } + } } private getTopHashtags() { diff --git a/src/app/media-wall/media-wall.component.ts b/src/app/media-wall/media-wall.component.ts index 5952c7b3f..f669f2972 100644 --- a/src/app/media-wall/media-wall.component.ts +++ b/src/app/media-wall/media-wall.component.ts @@ -2,19 +2,15 @@ import { Component, OnInit, OnDestroy, - ElementRef, ChangeDetectionStrategy, - ViewChild, ChangeDetectorRef } from '@angular/core'; -import { Router, ActivatedRoute, Params } from '@angular/router'; -import { Location } from '@angular/common'; -import { MatDialog, MatDialogRef } from '@angular/material'; +import { ActivatedRoute, Params } from '@angular/router'; +import { MatDialog } from '@angular/material'; import { MediaWallCustomizationComponent } from './media-wall-customization/media-wall-customization.component'; import { MediaWallQueryComponent } from './media-wall-query/media-wall-query.component'; import { MediaWallModerationComponent } from './media-wall-moderation/media-wall-moderation.component'; import { MediaWallDesignComponent } from './media-wall-design/media-wall-design.component'; -import { Title } from '@angular/platform-browser'; import { MasonryOptions } from '../app-masonry'; import { Observable, Subscription, timer } from 'rxjs'; @@ -25,9 +21,9 @@ import * as mediaWallAction from '../actions/media-wall-query'; import * as mediaWallModerationAction from '../actions/media-wall-moderation'; import * as mediaWallDesignAction from '../actions/media-wall-design'; import * as mediaWallCustomAction from '../actions/media-wall-custom'; - +import * as titleAction from '../actions/title'; import { Query } from '../models/query'; -import { ApiResponse, ApiResponseResult } from '../models/api-response'; +import { ApiResponseResult } from '../models/api-response'; import { WallHeader, WallBackground, WallCard } from '../models'; @@ -68,12 +64,9 @@ export class MediaWallComponent implements OnInit, OnDestroy { constructor( private route: ActivatedRoute, - private location: Location, - private elementRef: ElementRef, private store: Store, private ref: ChangeDetectorRef, - private dialog: MatDialog, - private titleService: Title + private dialog: MatDialog ) { } ngOnInit() { @@ -214,6 +207,9 @@ export class MediaWallComponent implements OnInit, OnDestroy { this.wallColumnCount$ = this.store.select(fromRoot.getWallColumnCount); this.wallDisplayHeader$ = this.store.select(fromRoot.getWallDisplayHeader); this.wallHeaderTitle$ = this.store.select(fromRoot.getWallHeaderTitle); + this.query$.subscribe(displayString => + this.store.dispatch(new titleAction.SetTitleAction(displayString.displayString + ' - Loklak Search' + ))); } public openDialog(event) { diff --git a/src/app/reducers/index.ts b/src/app/reducers/index.ts index a5ea1e660..c979c5f6e 100644 --- a/src/app/reducers/index.ts +++ b/src/app/reducers/index.ts @@ -1,7 +1,6 @@ import { createSelector } from 'reselect'; import { ActionReducerMap, MetaReducer } from '@ngrx/store'; import { environment } from '../../environments/environment'; -import { ApiResponse } from '../models/api-response'; /** diff --git a/src/app/services/search.service.ts b/src/app/services/search.service.ts index 0b4c8029a..a405e11dc 100644 --- a/src/app/services/search.service.ts +++ b/src/app/services/search.service.ts @@ -14,13 +14,23 @@ export class SearchService { ) { } public fetchQuery(query: string, config: SearchServiceConfig): Observable { - const jsonpUrl = 'https://api.loklak.org/api/search.json' + + let jsonpUrl = 'https://api.loklak.org/api/search.json' + '?q=' + query + '&minified=' + 'true' + '&source=' + config.source + '&maximumRecords=' + config.maximumRecords.toString() + '&timezoneOffset=' + config.getTimezoneOffset() + '&startRecord=' + config.startRecord.toString(); + + if (config.getAggregationFieldString()) { + jsonpUrl += '&fields=' + config.getAggregationFieldString() + + '&limit=' + config.aggregationLimit.toString(); + } + + if (config.getFilterString()) { + jsonpUrl += '&filter=' + config.getFilterString(); + } + return this.http .jsonp(jsonpUrl, 'callback') .pipe(