mirror of
https://github.com/fergalmoran/podnoms.git
synced 2025-12-28 20:28:33 +00:00
Push notifications added
This commit is contained in:
@@ -5,6 +5,7 @@ import { AuthService } from 'app/services/auth.service';
|
|||||||
import { AppInsightsService } from 'app/services/app-insights.service';
|
import { AppInsightsService } from 'app/services/app-insights.service';
|
||||||
import { SignalRService } from 'app/services/signalr.service';
|
import { SignalRService } from 'app/services/signalr.service';
|
||||||
import { ProfileService } from './services/profile.service';
|
import { ProfileService } from './services/profile.service';
|
||||||
|
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@@ -27,9 +28,9 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.loggedIn()) {
|
this._pushNotifications.requestPermissions();
|
||||||
this._pushNotifications.requestPermission();
|
|
||||||
|
|
||||||
|
if (this.loggedIn()) {
|
||||||
const user = this._profileService.getProfile().subscribe(u => {
|
const user = this._profileService.getProfile().subscribe(u => {
|
||||||
if (u) {
|
if (u) {
|
||||||
const chatterChannel = `${u.uid}_chatter`;
|
const chatterChannel = `${u.uid}_chatter`;
|
||||||
@@ -44,22 +45,10 @@ export class AppComponent implements OnInit {
|
|||||||
this._signalrService.connection.on(
|
this._signalrService.connection.on(
|
||||||
chatterChannel,
|
chatterChannel,
|
||||||
result => {
|
result => {
|
||||||
this._pushNotifications
|
this._pushNotifications.createNotification(
|
||||||
.create('PodNoms', { body: result })
|
'PodNoms',
|
||||||
.subscribe(
|
result
|
||||||
res =>
|
);
|
||||||
console.log(
|
|
||||||
'app.component',
|
|
||||||
'_pushNotifications',
|
|
||||||
res
|
|
||||||
),
|
|
||||||
err =>
|
|
||||||
console.log(
|
|
||||||
'app.component',
|
|
||||||
'_pushNotifications',
|
|
||||||
err
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import { AboutComponent } from './components/about/about.component';
|
|||||||
import { FooterComponent } from './components/footer/footer.component';
|
import { FooterComponent } from './components/footer/footer.component';
|
||||||
import { JobsService } from 'app/services/jobs.service';
|
import { JobsService } from 'app/services/jobs.service';
|
||||||
import { AppInsightsService } from 'app/services/app-insights.service';
|
import { AppInsightsService } from 'app/services/app-insights.service';
|
||||||
|
import { PushNotificationsService } from './services/push-notifications.service';
|
||||||
|
|
||||||
export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
||||||
return new AuthHttp(
|
return new AuthHttp(
|
||||||
@@ -100,7 +101,6 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
|||||||
ToastyModule.forRoot(),
|
ToastyModule.forRoot(),
|
||||||
DropzoneModule,
|
DropzoneModule,
|
||||||
ClipboardModule,
|
ClipboardModule,
|
||||||
PushNotificationsModule,
|
|
||||||
|
|
||||||
StoreModule.forRoot(reducers),
|
StoreModule.forRoot(reducers),
|
||||||
|
|
||||||
@@ -124,9 +124,9 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
|||||||
SignalRService,
|
SignalRService,
|
||||||
ProfileService,
|
ProfileService,
|
||||||
PodcastService,
|
PodcastService,
|
||||||
PushNotificationsService,
|
|
||||||
ImageService,
|
ImageService,
|
||||||
DebugService,
|
DebugService,
|
||||||
|
PushNotificationsService,
|
||||||
ChatterService,
|
ChatterService,
|
||||||
AppInsightsService,
|
AppInsightsService,
|
||||||
JobsService,
|
JobsService,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { DebugService } from 'app/services/debug.service';
|
import { DebugService } from 'app/services/debug.service';
|
||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
import { JobsService } from 'app/services/jobs.service';
|
import { JobsService } from 'app/services/jobs.service';
|
||||||
import { PushNotificationsService } from 'ng-push';
|
|
||||||
import { ChatterService } from 'app/services/chatter.service';
|
import { ChatterService } from 'app/services/chatter.service';
|
||||||
|
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-debug',
|
selector: 'app-debug',
|
||||||
@@ -57,7 +57,7 @@ export class DebugComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
sendChatter() {
|
sendChatter() {
|
||||||
this._chatterService.ping('Pong').subscribe(r => {
|
this._chatterService.ping('Pong').subscribe(r => {
|
||||||
this._pushNotifications.create('PodNoms', { body: r });
|
this._pushNotifications.createNotification('PodNoms', r);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
sendDesktopNotification() {
|
sendDesktopNotification() {
|
||||||
@@ -66,22 +66,10 @@ export class DebugComponent implements OnInit {
|
|||||||
'sendDesktopFunction',
|
'sendDesktopFunction',
|
||||||
this.notificationMessage
|
this.notificationMessage
|
||||||
);
|
);
|
||||||
this._pushNotifications
|
this._pushNotifications.createNotification(
|
||||||
.create('PodNoms', { body: this.notificationMessage })
|
'PodNoms',
|
||||||
.subscribe(
|
this.notificationMessage
|
||||||
res =>
|
);
|
||||||
console.log(
|
|
||||||
'debug.component',
|
|
||||||
'sendDesktopNotification',
|
|
||||||
res
|
|
||||||
),
|
|
||||||
err =>
|
|
||||||
console.log(
|
|
||||||
'debug.component',
|
|
||||||
'sendDesktopNotification',
|
|
||||||
err
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
processOrphans() {
|
processOrphans() {
|
||||||
this._jobsService
|
this._jobsService
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import * as fromPodcast from 'app/reducers';
|
|||||||
import * as fromPodcastActions from 'app/actions/podcast.actions';
|
import * as fromPodcastActions from 'app/actions/podcast.actions';
|
||||||
import * as fromEntriesActions from 'app/actions/entries.actions';
|
import * as fromEntriesActions from 'app/actions/entries.actions';
|
||||||
import { PodcastService } from 'app/services/podcast.service';
|
import { PodcastService } from 'app/services/podcast.service';
|
||||||
|
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-podcast',
|
selector: 'app-podcast',
|
||||||
|
|||||||
@@ -1,8 +1,40 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
export type Permission = 'denied' | 'granted' | 'default';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PushNotificationsService {
|
export class PushNotificationsService {
|
||||||
|
permission: Permission;
|
||||||
|
|
||||||
constructor() { }
|
constructor() {}
|
||||||
|
requestPermissions() {
|
||||||
|
if ('Notification' in window) {
|
||||||
|
Notification.requestPermission((status: any) => {
|
||||||
|
console.log(
|
||||||
|
'push-notifications.service',
|
||||||
|
'requestPermissions',
|
||||||
|
status
|
||||||
|
);
|
||||||
|
this.permission = status;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isSupported() {
|
||||||
|
return 'Notification' in window && this.permission == 'granted';
|
||||||
|
}
|
||||||
|
createNotification(subject: string, text: string) {
|
||||||
|
if (this.isSupported()) {
|
||||||
|
const options = {
|
||||||
|
body: text,
|
||||||
|
icon: 'https://podnoms.com/assets/img/logo-icon.png'
|
||||||
|
};
|
||||||
|
const n = new Notification(subject, options);
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
'push-notifications.service',
|
||||||
|
'createNotification',
|
||||||
|
'Notifications are not supported'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
server/Controllers/ChatterController.cs
Normal file
31
server/Controllers/ChatterController.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
using PodNoms.Api.Services.Hubs;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Controllers {
|
||||||
|
[Authorize]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class ChatterController : Controller {
|
||||||
|
private readonly IUserRepository _repository;
|
||||||
|
private readonly HubLifetimeManager<ChatterHub> _chatterHub;
|
||||||
|
public ChatterController(IUserRepository repository, HubLifetimeManager<ChatterHub> chatterHub) {
|
||||||
|
this._chatterHub = chatterHub;
|
||||||
|
this._repository = repository;
|
||||||
|
}
|
||||||
|
[HttpPost("ping")]
|
||||||
|
public async Task<ActionResult<string>> Ping([FromBody] string message) {
|
||||||
|
var email = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
|
||||||
|
|
||||||
|
var user = await this._repository.GetAsync(email);
|
||||||
|
await _chatterHub.SendAllAsync(
|
||||||
|
$"{user.Uid}_chatter",
|
||||||
|
new object[] { message });
|
||||||
|
return Ok(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
197
server/Migrations/20180316223756_UidToUser.Designer.cs
generated
Normal file
197
server/Migrations/20180316223756_UidToUser.Designer.cs
generated
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PodnomsDbContext))]
|
||||||
|
[Migration("20180316223756_UidToUser")]
|
||||||
|
partial class UidToUser
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.0-preview1-28290")
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsUnicode(true);
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.Property<int?>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("Podcasts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<long>("AudioFileSize");
|
||||||
|
|
||||||
|
b.Property<float>("AudioLength");
|
||||||
|
|
||||||
|
b.Property<string>("AudioUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Author");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<int?>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<bool>("Processed");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessingPayload");
|
||||||
|
|
||||||
|
b.Property<int>("ProcessingStatus");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("PodcastEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ApiKey")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate");
|
||||||
|
|
||||||
|
b.Property<string>("EmailAddress")
|
||||||
|
.HasMaxLength(100);
|
||||||
|
|
||||||
|
b.Property<string>("FullName")
|
||||||
|
.HasMaxLength(100);
|
||||||
|
|
||||||
|
b.Property<string>("ProfileImage");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("RefreshToken");
|
||||||
|
|
||||||
|
b.Property<string>("Sid")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("Uid")
|
||||||
|
.HasMaxLength(32);
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Slug")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[Slug] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PlaylistId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
server/Migrations/20180316223756_UidToUser.cs
Normal file
25
server/Migrations/20180316223756_UidToUser.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
public partial class UidToUser : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Uid",
|
||||||
|
table: "Users",
|
||||||
|
maxLength: 32,
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Uid",
|
||||||
|
table: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
197
server/Migrations/20180317002411_UidLenIncrease.Designer.cs
generated
Normal file
197
server/Migrations/20180317002411_UidLenIncrease.Designer.cs
generated
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PodnomsDbContext))]
|
||||||
|
[Migration("20180317002411_UidLenIncrease")]
|
||||||
|
partial class UidLenIncrease
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.0-preview1-28290")
|
||||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsUnicode(true);
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.Property<int?>("UserId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("Podcasts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<long>("AudioFileSize");
|
||||||
|
|
||||||
|
b.Property<float>("AudioLength");
|
||||||
|
|
||||||
|
b.Property<string>("AudioUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Author");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasDefaultValueSql("getdate()");
|
||||||
|
|
||||||
|
b.Property<string>("Description");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl");
|
||||||
|
|
||||||
|
b.Property<int?>("PlaylistId");
|
||||||
|
|
||||||
|
b.Property<int>("PodcastId");
|
||||||
|
|
||||||
|
b.Property<bool>("Processed");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessingPayload");
|
||||||
|
|
||||||
|
b.Property<int>("ProcessingStatus");
|
||||||
|
|
||||||
|
b.Property<string>("SourceUrl");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("Uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlaylistId");
|
||||||
|
|
||||||
|
b.HasIndex("PodcastId");
|
||||||
|
|
||||||
|
b.ToTable("PodcastEntries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ApiKey")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateDate");
|
||||||
|
|
||||||
|
b.Property<string>("EmailAddress")
|
||||||
|
.HasMaxLength(100);
|
||||||
|
|
||||||
|
b.Property<string>("FullName")
|
||||||
|
.HasMaxLength(100);
|
||||||
|
|
||||||
|
b.Property<string>("ProfileImage");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderId")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("RefreshToken");
|
||||||
|
|
||||||
|
b.Property<string>("Sid")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<string>("Uid")
|
||||||
|
.HasMaxLength(50);
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdateDate");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Slug")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[Slug] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Playlist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.Podcast", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PodNoms.Api.Models.PodcastEntry", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PodNoms.Api.Models.Playlist")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PlaylistId");
|
||||||
|
|
||||||
|
b.HasOne("PodNoms.Api.Models.Podcast", "Podcast")
|
||||||
|
.WithMany("PodcastEntries")
|
||||||
|
.HasForeignKey("PodcastId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
server/Migrations/20180317002411_UidLenIncrease.cs
Normal file
33
server/Migrations/20180317002411_UidLenIncrease.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Migrations
|
||||||
|
{
|
||||||
|
public partial class UidLenIncrease : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "Uid",
|
||||||
|
table: "Users",
|
||||||
|
maxLength: 50,
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldMaxLength: 32,
|
||||||
|
oldNullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "Uid",
|
||||||
|
table: "Users",
|
||||||
|
maxLength: 32,
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldMaxLength: 50,
|
||||||
|
oldNullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
server/Services/Hubs/ChatterHub.cs
Normal file
14
server/Services/Hubs/ChatterHub.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Services.Hubs {
|
||||||
|
[Authorize]
|
||||||
|
public class ChatterHub : Hub {
|
||||||
|
public async Task SendMessage(string user, string message) {
|
||||||
|
string timestamp = DateTime.Now.ToShortTimeString();
|
||||||
|
await Clients.All.SendAsync($"{user}_chatter", timestamp, user, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user