Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display correct timezone, handle raw input #40

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions app/Traits/ScrapesRates.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use App\Models\Rate;
use Carbon\CarbonInterval;
use Carbon\CarbonTimeZone;
use DateTime;
use Error;
use Exception;
Expand Down Expand Up @@ -252,7 +251,13 @@ private function cleanRate(string $value, string $locale): float
}
}

return $amount;
/**
* Remove extra spaces
*/
$amount = Str::squish($amount);

return floatval($amount);

}

/**
Expand All @@ -264,16 +269,23 @@ private function clean(string $value): string
$value = strip_tags($value);
$value = str_replace(' ', ' ', $value);
$value = preg_replace('/\s+/', ' ', $value);
$value = trim($value);

// $value = strip_tags(trim(html_entity_decode($value), " \t\n\r\0\x0B\xC2\xA0"));

/**
* Normalize the string
*/
$value = Str::transliterate($value);
$value = Str::ascii($value);

/**
* Remove all non-alphanumeric characters except spaces
*/
return implode(' ', array_map(function (string $word): string {
$value = implode(' ', array_map(function (string $word): string {
return trim($word, '-,:;\'"()[]{}<>!?*');
}, explode(' ', $value)));

return Str::squish($value);
}

/**
Expand All @@ -294,7 +306,9 @@ private function cleanDate(string $value, string $timezone): Carbon
$parsed = $parser->parse($rawDate, true);

if ($parsed !== false) {
return Carbon::parse($parsed, CarbonTimeZone::create($timezone))->shiftTimezone('UTC');

// Parsed date is in UTC, shift to source timezone
return Carbon::parse($parsed)->shiftTimezone($timezone)->setTimezone('UTC');
}
} catch (Exception|Error) {
//do nothing
Expand Down Expand Up @@ -335,6 +349,6 @@ private function cleanDate(string $value, string $timezone): Carbon
/**
* Parse the date
*/
return Carbon::parse($rawDate, CarbonTimeZone::create($timezone))->shiftTimezone('UTC');
return Carbon::parse($rawDate)->shiftTimezone($timezone)->setTimezone('UTC');
}
}
22 changes: 19 additions & 3 deletions resources/js/front-end/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {HttpClientModule} from '@angular/common/http';

import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {CommonModule, NgOptimizedImage} from "@angular/common";
import {CommonModule, DATE_PIPE_DEFAULT_OPTIONS, NgOptimizedImage} from "@angular/common";
import {GraphQLModule} from "./modules/graphql.module";
import {HeaderComponent} from "./sections/other/header/header.component";
import {HeroComponent} from "./sections/other/hero/hero.component";
Expand All @@ -21,6 +21,8 @@ import {RatesDetailedComponent} from "./sections/landing/rates-display/rates-det
import {RatesCardComponent} from "./sections/landing/rates-display/rates-card/rates-card.component";
import {RatesItemComponent} from "./sections/landing/rates-display/rates-item/rates-item.component";
import {HomeComponent} from "./pages/home/home.component";
import {DateTime, Settings} from "luxon";
import {LocalDatePipe} from './pipes/local-date.pipe';

@NgModule({
declarations: [
Expand All @@ -38,7 +40,8 @@ import {HomeComponent} from "./pages/home/home.component";
RatesDetailedComponent,
RatesCardComponent,
RatesItemComponent,
HomeComponent
HomeComponent,
LocalDatePipe
],
imports: [
CommonModule,
Expand All @@ -48,10 +51,23 @@ import {HomeComponent} from "./pages/home/home.component";
NgOptimizedImage,
GraphQLModule
],
providers: [],
providers: [
{
provide: DATE_PIPE_DEFAULT_OPTIONS,
useValue: {
timezone: DateTime.now().zoneName,
dateFormat: 'MMM d, y HH:mm'
}
}
],
bootstrap: [
AppComponent
],
})
export class AppModule {

constructor() {
Settings.defaultZone = "utc";
}

}
8 changes: 8 additions & 0 deletions resources/js/front-end/app/pipes/local-date.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { LocalDatePipe } from './local-date.pipe';

describe('LocalDatePipe', () => {
it('create an instance', () => {
const pipe = new LocalDatePipe();
expect(pipe).toBeTruthy();
});
});
27 changes: 27 additions & 0 deletions resources/js/front-end/app/pipes/local-date.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {DATE_PIPE_DEFAULT_OPTIONS, DatePipe, DatePipeConfig} from "@angular/common";
import {DateTime} from "luxon";

@Pipe({
name: 'localDate'
})
export class LocalDatePipe implements PipeTransform {

constructor(
@Inject(DATE_PIPE_DEFAULT_OPTIONS)
protected datePipeConfig: DatePipeConfig,
@Inject(LOCALE_ID)
protected localeId: string
) {
}

transform(value: number): string | null {

const pipe: DatePipe = new DatePipe(this.localeId, this.datePipeConfig.timezone, this.datePipeConfig);

const date: number = DateTime.fromSeconds(value).toMillis();

return pipe.transform(date, this.datePipeConfig.dateFormat, this.datePipeConfig.timezone);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,32 @@
<ng-container *ngFor="let currency of currencies$">
<tr style="border-bottom: none;">
<th [style.visibility]="!currency.expanded ? 'visible' : 'hidden'">
<p class="mb-0">{{currency.currency | uppercase}}</p>
<p class="mb-0">{{ currency.currency | uppercase }}</p>
<small *ngIf="currency.currency.toUpperCase() !== currency.currency_base.toUpperCase()"
class="font-size-small">
{{currency.currency_base | uppercase}}
{{ currency.currency_base | uppercase }}
</small>
</th>
<td [style.visibility]="!currency.expanded ? 'visible' : 'hidden'" class="hidden-small">
<p class="mb-0">
<span class="text-white">
{{currency.minRate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5'}}
{{ currency.minRate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5' }}
</span>
<span *ngIf="currency.maxRate.rate != currency.minRate.rate" class="text-white">
&dash;
{{currency.maxRate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5'}}
{{ currency.maxRate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5' }}
</span>
</p>
</td>
<td [style.visibility]="!currency.expanded ? 'visible' : 'hidden'" class="hidden-medium"
style="text-overflow: fade(25%); white-space: nowrap">
{{DateTime.fromSeconds(currency.last_updated).toJSDate() | date:'MMM d, y HH:mm'}}
{{ currency.last_updated | localDate }}
</td>
<td style="width: 1%">
<button (click)="onToggleExpanded($event, currency)"
[title]="currency.expanded ?'Compat': 'Detailed' " class="button"
type="button">
{{currency.expanded ? 'Less &triangle;' : 'More &triangledown;' }}
{{ currency.expanded ? 'Less &triangle;' : 'More &triangledown;' }}
</button>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {Component, Input, OnInit} from '@angular/core';
import {Dictionary} from "lodash";
import RateAggregate from "../../../../@types/rate-aggregate";
import {DateTime} from "luxon";

@Component({
selector: 'app-rates-detailed',
Expand All @@ -12,7 +11,6 @@ export class RatesDetailedComponent implements OnInit {

@Input("currencies") currencies$: RateAggregate[] = [];
@Input("data") data$: Dictionary<any> = {};
protected readonly DateTime = DateTime;

constructor() {
this.ngOnInit = this.ngOnInit.bind(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
<tr>
<th class="text-white" colspan="2">
<span class="font-xxx-large">
{{currency.currency | uppercase}}
{{ currency.currency | uppercase }}
</span>
<small *ngIf="currency.currency.toUpperCase() !== currency.currency_base.toUpperCase()">
{{currency.currency_base | uppercase}}
{{ currency.currency_base | uppercase }}
</small>
</th>
<th colspan="2" style="text-align: right" title="When we last scanned rates.">
<p class="mb-0">{{DateTime.fromSeconds(currency.last_checked).toJSDate() | date:'MMM d y, HH:mm'}}</p>
<p class="mb-0">{{ currency.last_checked| localDate }}</p>
<small class="font-size-small">Checked</small>
</th>
<th colspan="2" style="text-align: right" title="When rate was last updated.">
<p class="mb-0">{{DateTime.fromSeconds(currency.last_updated).toJSDate() | date:'MMM d, y HH:mm'}}</p>
<p class="mb-0">{{ currency.last_updated | localDate }}</p>
<small class="font-size-small">Updated</small>
</th>
</tr>
<tr>
<th class="text-center">
<p class="mb-0 text-white font-bold">{{ currency.aggregated.max | currency: currency.currency_base:'symbol-narrow':'1.0-2'}}</p>
<p class="mb-0 text-white font-bold">{{ currency.aggregated.max | currency: currency.currency_base:'symbol-narrow':'1.0-2' }}</p>
<small class="font-size-small">Max</small>
</th>
<th class="text-center">
Expand Down Expand Up @@ -49,7 +49,7 @@
<td colspan="3" style="vertical-align: bottom">
<ul>
<li *ngFor="let url of currency.urls">
<a [href]="url.toString()" target="_blank">{{url.hostname}}</a>
<a [href]="url.toString()" target="_blank">{{ url.hostname }}</a>
</li>
</ul>
</td>
Expand All @@ -71,13 +71,13 @@
<tbody>
<tr *ngFor="let rate of currency.rates">
<th class="text-white text-center">
{{rate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5'}}
{{ rate.rate | currency: currency.currency_base:'symbol-narrow':'1.0-5' }}
</th>
<td class="text-center">
{{rate.last_rate | currency: currency.currency_base:'symbol-narrow':'1.0-5'}}
{{ rate.last_rate | currency: currency.currency_base:'symbol-narrow':'1.0-5' }}
</td>
<td class="text-center">
{{ (rate.rate - rate.last_rate) / rate.last_rate | percent:'1.2'}}
{{ (rate.rate - rate.last_rate) / rate.last_rate | percent:'1.2' }}
</td>
</tr>
</tbody>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {Component, Input, OnInit} from '@angular/core';
import RateAggregate from "../../../../@types/rate-aggregate";
import {DateTime} from "luxon";

@Component({
selector: 'app-rates-item',
Expand All @@ -11,8 +10,6 @@ export class RatesItemComponent implements OnInit {

@Input("currency") currency!: RateAggregate;

protected readonly DateTime = DateTime;

constructor() {
this.ngOnInit = this.ngOnInit.bind(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Last Checked
</p>
<h2 *ngIf="lastChecked$ !== undefined" [attr.data-checked]="lastChecked$" class="section-title mt-0">
{{ DateTime.fromSeconds(lastChecked$).toJSDate() | date:'MMM d, y HH:mm' }}
{{ lastChecked$ | localDate }}
</h2>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export class RatesComponent implements OnInit {

ratesDisplay: string = "";

protected readonly DateTime = DateTime;

constructor(private rateService: RatesService, private animeService: AnimeService) {
this.ngOnInit = this.ngOnInit.bind(this);

Expand Down Expand Up @@ -79,7 +77,7 @@ export class RatesComponent implements OnInit {
});

// Last Checked
this.lastChecked$ = maxBy<Rate>(data["rates"], "last_checked")?.last_checked || DateTime.now().toSeconds();
this.lastChecked$ = maxBy<Rate>(data["rates"], "last_checked")?.last_checked || DateTime.utc().toSeconds();

setTimeout((): void => {
this.animeService.reviewComponents();
Expand Down