mirror of
https://github.com/fergalmoran/podnoms.git
synced 2025-12-22 09:18:08 +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 { SignalRService } from 'app/services/signalr.service';
|
||||
import { ProfileService } from './services/profile.service';
|
||||
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -27,9 +28,9 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.loggedIn()) {
|
||||
this._pushNotifications.requestPermission();
|
||||
this._pushNotifications.requestPermissions();
|
||||
|
||||
if (this.loggedIn()) {
|
||||
const user = this._profileService.getProfile().subscribe(u => {
|
||||
if (u) {
|
||||
const chatterChannel = `${u.uid}_chatter`;
|
||||
@@ -44,22 +45,10 @@ export class AppComponent implements OnInit {
|
||||
this._signalrService.connection.on(
|
||||
chatterChannel,
|
||||
result => {
|
||||
this._pushNotifications
|
||||
.create('PodNoms', { body: result })
|
||||
.subscribe(
|
||||
res =>
|
||||
console.log(
|
||||
'app.component',
|
||||
'_pushNotifications',
|
||||
res
|
||||
),
|
||||
err =>
|
||||
console.log(
|
||||
'app.component',
|
||||
'_pushNotifications',
|
||||
err
|
||||
)
|
||||
);
|
||||
this._pushNotifications.createNotification(
|
||||
'PodNoms',
|
||||
result
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
@@ -51,6 +51,7 @@ import { AboutComponent } from './components/about/about.component';
|
||||
import { FooterComponent } from './components/footer/footer.component';
|
||||
import { JobsService } from 'app/services/jobs.service';
|
||||
import { AppInsightsService } from 'app/services/app-insights.service';
|
||||
import { PushNotificationsService } from './services/push-notifications.service';
|
||||
|
||||
export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
||||
return new AuthHttp(
|
||||
@@ -100,7 +101,6 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
||||
ToastyModule.forRoot(),
|
||||
DropzoneModule,
|
||||
ClipboardModule,
|
||||
PushNotificationsModule,
|
||||
|
||||
StoreModule.forRoot(reducers),
|
||||
|
||||
@@ -124,9 +124,9 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) {
|
||||
SignalRService,
|
||||
ProfileService,
|
||||
PodcastService,
|
||||
PushNotificationsService,
|
||||
ImageService,
|
||||
DebugService,
|
||||
PushNotificationsService,
|
||||
ChatterService,
|
||||
AppInsightsService,
|
||||
JobsService,
|
||||
|
||||
@@ -4,8 +4,8 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { DebugService } from 'app/services/debug.service';
|
||||
import { environment } from 'environments/environment';
|
||||
import { JobsService } from 'app/services/jobs.service';
|
||||
import { PushNotificationsService } from 'ng-push';
|
||||
import { ChatterService } from 'app/services/chatter.service';
|
||||
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-debug',
|
||||
@@ -57,7 +57,7 @@ export class DebugComponent implements OnInit {
|
||||
}
|
||||
sendChatter() {
|
||||
this._chatterService.ping('Pong').subscribe(r => {
|
||||
this._pushNotifications.create('PodNoms', { body: r });
|
||||
this._pushNotifications.createNotification('PodNoms', r);
|
||||
});
|
||||
}
|
||||
sendDesktopNotification() {
|
||||
@@ -66,22 +66,10 @@ export class DebugComponent implements OnInit {
|
||||
'sendDesktopFunction',
|
||||
this.notificationMessage
|
||||
);
|
||||
this._pushNotifications
|
||||
.create('PodNoms', { body: this.notificationMessage })
|
||||
.subscribe(
|
||||
res =>
|
||||
console.log(
|
||||
'debug.component',
|
||||
'sendDesktopNotification',
|
||||
res
|
||||
),
|
||||
err =>
|
||||
console.log(
|
||||
'debug.component',
|
||||
'sendDesktopNotification',
|
||||
err
|
||||
)
|
||||
);
|
||||
this._pushNotifications.createNotification(
|
||||
'PodNoms',
|
||||
this.notificationMessage
|
||||
);
|
||||
}
|
||||
processOrphans() {
|
||||
this._jobsService
|
||||
|
||||
@@ -14,6 +14,7 @@ import * as fromPodcast from 'app/reducers';
|
||||
import * as fromPodcastActions from 'app/actions/podcast.actions';
|
||||
import * as fromEntriesActions from 'app/actions/entries.actions';
|
||||
import { PodcastService } from 'app/services/podcast.service';
|
||||
import { PushNotificationsService } from 'app/services/push-notifications.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-podcast',
|
||||
|
||||
@@ -1,8 +1,40 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export type Permission = 'denied' | 'granted' | 'default';
|
||||
|
||||
@Injectable()
|
||||
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