diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 77b50af0..ce95dcf3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -49,6 +49,7 @@ import { TutorialComponent } from './components/tutorial/tutorial.component'; import { NotificationHubComponent } from './components/notification-hub/notification-hub.component'; import { NotificationService } from "./services/notification.service"; import { MediaViewerComponent } from './components/media-viewer/media-viewer.component'; +import { CreateStatusComponent } from './components/create-status/create-status.component'; const routes: Routes = [ { path: "", redirectTo: "home", pathMatch: "full" }, @@ -87,7 +88,8 @@ const routes: Routes = [ StreamEditionComponent, TutorialComponent, NotificationHubComponent, - MediaViewerComponent + MediaViewerComponent, + CreateStatusComponent ], imports: [ FontAwesomeModule, diff --git a/src/app/components/create-status/create-status.component.html b/src/app/components/create-status/create-status.component.html new file mode 100644 index 00000000..1b75b862 --- /dev/null +++ b/src/app/components/create-status/create-status.component.html @@ -0,0 +1,13 @@ +
+ + + + + + + +
\ No newline at end of file diff --git a/src/app/components/create-status/create-status.component.scss b/src/app/components/create-status/create-status.component.scss new file mode 100644 index 00000000..b1abcad9 --- /dev/null +++ b/src/app/components/create-status/create-status.component.scss @@ -0,0 +1,36 @@ +@import "variables"; +@import "panel"; +@import "buttons"; +$btn-send-status-width: 60px; +.form-control { + margin: 0 0 5px 5px; + width: calc(100% - 10px); + background-color: $column-color; + border-color: $status-secondary-color; + color: #fff; + font-size: $default-font-size; + + &:focus { + box-shadow: none; + } + + &--privacy { + display: inline-block; + width: calc(100% - 15px - #{$btn-send-status-width}); + } +} + +.btn-custom-primary { + display: inline-block; + width: $btn-send-status-width; + position: relative; + top: -1px; + left: 5px; // background-color: orange; + // border-color: orange; + // color: black; + font-weight: 500; // &:hover { + // } + // &:focus { + // border-color: darkblue; + // } +} \ No newline at end of file diff --git a/src/app/components/create-status/create-status.component.spec.ts b/src/app/components/create-status/create-status.component.spec.ts new file mode 100644 index 00000000..2f98b53a --- /dev/null +++ b/src/app/components/create-status/create-status.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateStatusComponent } from './create-status.component'; + +describe('CreateStatusComponent', () => { + let component: CreateStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateStatusComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/create-status/create-status.component.ts b/src/app/components/create-status/create-status.component.ts new file mode 100644 index 00000000..005b47c0 --- /dev/null +++ b/src/app/components/create-status/create-status.component.ts @@ -0,0 +1,135 @@ +import { Component, OnInit, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core'; +import { HttpErrorResponse } from '@angular/common/http'; + +import { MastodonService, VisibilityEnum } from '../../services/mastodon.service'; +import { Status } from '../../services/models/mastodon.interfaces'; +import { ToolsService } from '../../services/tools.service'; +import { NotificationService } from '../../services/notification.service'; +import { StatusWrapper } from '../../models/common.model'; + +@Component({ + selector: 'app-create-status', + templateUrl: './create-status.component.html', + styleUrls: ['./create-status.component.scss'] +}) +export class CreateStatusComponent implements OnInit { + title: string; + status: string = ''; + + @Input() statusReplyingToWrapper: StatusWrapper; + @Output() onClose = new EventEmitter(); + @ViewChild('reply') replyElement: ElementRef; + + private statusReplyingTo: Status; + + selectedPrivacy = 'Public'; + privacyList: string[] = ['Public', 'Unlisted', 'Follows-only', 'DM']; + + constructor( + // private readonly store: Store, + private readonly notificationService: NotificationService, + private readonly toolsService: ToolsService, + private readonly mastodonService: MastodonService) { } + + ngOnInit() { + if (this.statusReplyingToWrapper) { + if (this.statusReplyingToWrapper.status.reblog) { + this.statusReplyingTo = this.statusReplyingToWrapper.status.reblog; + } else { + this.statusReplyingTo = this.statusReplyingToWrapper.status; + } + + // const mentions = [...this.statusReplyingTo.mentions.map(x => x.acct), this.statusReplyingTo.account.acct]; + // let uniqueMentions = []; + // for(const mention of mentions){ + // if(!uniqueMentions.includes(mention)){ + // uniqueMentions.push(mention); + // } + // } + + const uniqueMentions = this.getMentions(this.statusReplyingTo); + for (const mention of uniqueMentions) { + this.status += `@${mention} `; + } + } + + setTimeout(() => { + this.replyElement.nativeElement.focus(); + }, 0); + } + + private getMentions(status: Status): string[]{ + const mentions = [...status.mentions.map(x => x.acct), status.account.acct]; + let uniqueMentions = []; + for(let mention of mentions){ + if(!uniqueMentions.includes(mention)){ + // if(!mention.includes('@')){ + // mention += `@${status.}`; + // } + uniqueMentions.push(mention); + } + } + return uniqueMentions; + } + + onSubmit(): boolean { + let visibility: VisibilityEnum = VisibilityEnum.Unknown; + switch (this.selectedPrivacy) { //FIXME: in case of responding, set the visibility to original + case 'Public': + visibility = VisibilityEnum.Public; + break; + case 'Unlisted': + visibility = VisibilityEnum.Unlisted; + break; + case 'Follows-only': + visibility = VisibilityEnum.Private; + break; + case 'DM': + visibility = VisibilityEnum.Direct; + break; + } + + let spoiler = this.title; + if (this.statusReplyingToWrapper) { + spoiler = this.statusReplyingTo.spoiler_text; + } + + const acc = this.toolsService.getSelectedAccounts()[0]; + + let usableStatus: Promise; + if (this.statusReplyingToWrapper) { + usableStatus = this.toolsService.getStatusUsableByAccount(acc, this.statusReplyingToWrapper); + } else { + usableStatus = Promise.resolve(null); + } + + usableStatus + .then((status: Status) => { + let inReplyToId = null; + if (status) { + inReplyToId = status.id; + } + return this.mastodonService.postNewStatus(acc, this.status, visibility, spoiler, inReplyToId); + }) + .then((res: Status) => { + this.title = ''; + this.status = ''; + this.onClose.emit(); + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }); + + return false; + } + + // private getRegisteredAccounts(): AccountInfo[] { + // var regAccounts = this.store.snapshot().registeredaccounts.accounts; + // return regAccounts; + // } + + onCtrlEnter(): boolean { + this.onSubmit(); + return false; + } +} diff --git a/src/app/components/floating-column/add-new-account/add-new-account.component.html b/src/app/components/floating-column/add-new-account/add-new-account.component.html index 76cee452..10a2c071 100644 --- a/src/app/components/floating-column/add-new-account/add-new-account.component.html +++ b/src/app/components/floating-column/add-new-account/add-new-account.component.html @@ -8,5 +8,4 @@
- \ No newline at end of file diff --git a/src/app/components/floating-column/add-new-status/add-new-status.component.html b/src/app/components/floating-column/add-new-status/add-new-status.component.html index 247047d3..e858fd63 100644 --- a/src/app/components/floating-column/add-new-status/add-new-status.component.html +++ b/src/app/components/floating-column/add-new-status/add-new-status.component.html @@ -1,17 +1,15 @@

new message

-
- + -
- + --> +
\ No newline at end of file diff --git a/src/app/components/floating-column/add-new-status/add-new-status.component.ts b/src/app/components/floating-column/add-new-status/add-new-status.component.ts index 69fa5720..ec9f659c 100644 --- a/src/app/components/floating-column/add-new-status/add-new-status.component.ts +++ b/src/app/components/floating-column/add-new-status/add-new-status.component.ts @@ -14,12 +14,12 @@ import { NavigationService } from '../../../services/navigation.service'; styleUrls: ['./add-new-status.component.scss'] }) export class AddNewStatusComponent implements OnInit { - @Input() title: string; - @Input() status: string; - @ViewChild('reply') replyElement: ElementRef; + // @Input() title: string; + // @Input() status: string; + // @ViewChild('reply') replyElement: ElementRef; - selectedPrivacy = 'Public'; - privacyList: string[] = ['Public', 'Unlisted', 'Follows-only', 'DM']; + // selectedPrivacy = 'Public'; + // privacyList: string[] = ['Public', 'Unlisted', 'Follows-only', 'DM']; constructor( private readonly store: Store, @@ -28,58 +28,62 @@ export class AddNewStatusComponent implements OnInit { private readonly mastodonService: MastodonService) { } ngOnInit() { - setTimeout(() => { - this.replyElement.nativeElement.focus(); - }, 0); + // setTimeout(() => { + // this.replyElement.nativeElement.focus(); + // }, 0); } - onSubmit(): boolean { - const accounts = this.getRegisteredAccounts(); - const selectedAccounts = accounts.filter(x => x.isSelected); - - let visibility: VisibilityEnum = VisibilityEnum.Unknown; - switch (this.selectedPrivacy) { - case 'Public': - visibility = VisibilityEnum.Public; - break; - case 'Unlisted': - visibility = VisibilityEnum.Unlisted; - break; - case 'Follows-only': - visibility = VisibilityEnum.Private; - break; - case 'DM': - visibility = VisibilityEnum.Direct; - break; - } - - let spoiler = this.title; - if(spoiler === '') { - spoiler = null; - } - - for (const acc of selectedAccounts) { - this.mastodonService.postNewStatus(acc, this.status, visibility, spoiler) - .then((res: Status) => { - this.title = ''; - this.status = ''; - this.navigationService.closePanel(); - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); - } - - return false; + closeColumn() { + this.navigationService.closePanel(); } - private getRegisteredAccounts(): AccountInfo[] { - var regAccounts = this.store.snapshot().registeredaccounts.accounts; - return regAccounts; - } + // onSubmit(): boolean { + // const accounts = this.getRegisteredAccounts(); + // const selectedAccounts = accounts.filter(x => x.isSelected); - onCtrlEnter(): boolean { - this.onSubmit(); - return false; - } + // let visibility: VisibilityEnum = VisibilityEnum.Unknown; + // switch (this.selectedPrivacy) { + // case 'Public': + // visibility = VisibilityEnum.Public; + // break; + // case 'Unlisted': + // visibility = VisibilityEnum.Unlisted; + // break; + // case 'Follows-only': + // visibility = VisibilityEnum.Private; + // break; + // case 'DM': + // visibility = VisibilityEnum.Direct; + // break; + // } + + // let spoiler = this.title; + // if(spoiler === '') { + // spoiler = null; + // } + + // for (const acc of selectedAccounts) { + // this.mastodonService.postNewStatus(acc, this.status, visibility, spoiler) + // .then((res: Status) => { + // this.title = ''; + // this.status = ''; + // this.navigationService.closePanel(); + // }) + // .catch((err: HttpErrorResponse) => { + // this.notificationService.notifyHttpError(err); + // }); + // } + + // return false; + // } + + // private getRegisteredAccounts(): AccountInfo[] { + // var regAccounts = this.store.snapshot().registeredaccounts.accounts; + // return regAccounts; + // } + + // onCtrlEnter(): boolean { + // this.onSubmit(); + // return false; + // } } diff --git a/src/app/components/floating-column/search/search.component.ts b/src/app/components/floating-column/search/search.component.ts index 584aaed3..9cc63479 100644 --- a/src/app/components/floating-column/search/search.component.ts +++ b/src/app/components/floating-column/search/search.component.ts @@ -5,8 +5,8 @@ import { MastodonService } from '../../../services/mastodon.service'; import { AccountInfo } from '../../../states/accounts.state'; import { Results, Account } from '../../../services/models/mastodon.interfaces'; import { ToolsService, OpenThreadEvent } from '../../../services/tools.service'; -import { StatusWrapper } from '../../stream/stream.component'; import { NotificationService } from '../../../services/notification.service'; +import { StatusWrapper } from '../../../models/common.model'; @Component({ selector: 'app-search', diff --git a/src/app/components/stream/status/action-bar/action-bar.component.ts b/src/app/components/stream/status/action-bar/action-bar.component.ts index 13a335ed..41c3d3c1 100644 --- a/src/app/components/stream/status/action-bar/action-bar.component.ts +++ b/src/app/components/stream/status/action-bar/action-bar.component.ts @@ -5,12 +5,12 @@ import { Observable, Subscription } from 'rxjs'; import { faWindowClose, faReply, faRetweet, faStar } from "@fortawesome/free-solid-svg-icons"; import { faWindowClose as faWindowCloseRegular } from "@fortawesome/free-regular-svg-icons"; -import { StatusWrapper } from '../../stream.component'; import { MastodonService } from '../../../../services/mastodon.service'; import { AccountInfo } from '../../../../states/accounts.state'; import { Status } from '../../../../services/models/mastodon.interfaces'; import { ToolsService } from '../../../../services/tools.service'; import { NotificationService } from '../../../../services/notification.service'; +import { StatusWrapper } from '../../../../models/common.model'; @Component({ selector: 'app-action-bar', diff --git a/src/app/components/stream/status/reply-to-status/reply-to-status.component.ts b/src/app/components/stream/status/reply-to-status/reply-to-status.component.ts index cacbde8a..6c20b00a 100644 --- a/src/app/components/stream/status/reply-to-status/reply-to-status.component.ts +++ b/src/app/components/stream/status/reply-to-status/reply-to-status.component.ts @@ -1,12 +1,11 @@ import { Component, OnInit, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core'; -// import { Store } from '@ngxs/store'; +import { HttpErrorResponse } from '@angular/common/http'; + import { MastodonService, VisibilityEnum } from '../../../../services/mastodon.service'; -// import { AccountInfo } from '../../../../states/accounts.state'; -import { StatusWrapper } from '../../stream.component'; import { Status } from '../../../../services/models/mastodon.interfaces'; import { ToolsService } from '../../../../services/tools.service'; import { NotificationService } from '../../../../services/notification.service'; -import { HttpErrorResponse } from '@angular/common/http'; +import { StatusWrapper } from '../../../../models/common.model'; @Component({ selector: 'app-reply-to-status', diff --git a/src/app/components/stream/status/status.component.html b/src/app/components/stream/status/status.component.html index 7802c346..4af9cc53 100644 --- a/src/app/components/stream/status/status.component.html +++ b/src/app/components/stream/status/status.component.html @@ -50,6 +50,8 @@ - - + + + \ No newline at end of file diff --git a/src/app/components/stream/status/status.component.ts b/src/app/components/stream/status/status.component.ts index 6cfbcf2b..68cfced7 100644 --- a/src/app/components/stream/status/status.component.ts +++ b/src/app/components/stream/status/status.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from "@angular/core"; import { Status, Account } from "../../../services/models/mastodon.interfaces"; -import { StatusWrapper } from "../stream.component"; import { OpenThreadEvent } from "../../../services/tools.service"; import { ActionBarComponent } from "./action-bar/action-bar.component"; +import { StatusWrapper } from '../../../models/common.model'; @Component({ selector: "app-status", diff --git a/src/app/components/stream/stream-statuses/stream-statuses.component.ts b/src/app/components/stream/stream-statuses/stream-statuses.component.ts index 926bc205..6f96127e 100644 --- a/src/app/components/stream/stream-statuses/stream-statuses.component.ts +++ b/src/app/components/stream/stream-statuses/stream-statuses.component.ts @@ -8,9 +8,9 @@ import { AccountInfo } from '../../../states/accounts.state'; import { StreamingService, EventEnum, StreamingWrapper, StatusUpdate } from '../../../services/streaming.service'; import { Status } from '../../../services/models/mastodon.interfaces'; import { MastodonService } from '../../../services/mastodon.service'; -import { StatusWrapper } from '../stream.component'; import { NotificationService } from '../../../services/notification.service'; import { OpenThreadEvent, ToolsService } from '../../../services/tools.service'; +import { StatusWrapper } from '../../../models/common.model'; @Component({ selector: 'app-stream-statuses', diff --git a/src/app/components/stream/stream.component.ts b/src/app/components/stream/stream.component.ts index 8a252728..3369f18f 100644 --- a/src/app/components/stream/stream.component.ts +++ b/src/app/components/stream/stream.component.ts @@ -97,9 +97,3 @@ export class StreamComponent implements OnInit { } } -export class StatusWrapper { - constructor( - public status: Status, - public provider: AccountInfo - ) { } -} \ No newline at end of file diff --git a/src/app/components/stream/thread/thread.component.ts b/src/app/components/stream/thread/thread.component.ts index e2ffe40c..569d943f 100644 --- a/src/app/components/stream/thread/thread.component.ts +++ b/src/app/components/stream/thread/thread.component.ts @@ -1,13 +1,12 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; -import { StatusWrapper } from '../stream.component'; import { MastodonService } from '../../../services/mastodon.service'; import { ToolsService, OpenThreadEvent } from '../../../services/tools.service'; import { Results, Context, Status } from '../../../services/models/mastodon.interfaces'; import { NotificationService } from '../../../services/notification.service'; import { AccountInfo } from '../../../states/accounts.state'; -import { StreamStatusesComponent } from '../stream-statuses/stream-statuses.component'; +import { StatusWrapper } from '../../../models/common.model'; @Component({ selector: 'app-thread', diff --git a/src/app/components/stream/user-profile/user-profile.component.ts b/src/app/components/stream/user-profile/user-profile.component.ts index b47536f1..0793e7e2 100644 --- a/src/app/components/stream/user-profile/user-profile.component.ts +++ b/src/app/components/stream/user-profile/user-profile.component.ts @@ -8,9 +8,9 @@ import { Store } from '@ngxs/store'; import { Account, Status, Relationship } from "../../../services/models/mastodon.interfaces"; import { MastodonService } from '../../../services/mastodon.service'; import { ToolsService, OpenThreadEvent } from '../../../services/tools.service'; -import { StatusWrapper } from '../stream.component'; import { NotificationService } from '../../../services/notification.service'; import { AccountInfo } from '../../../states/accounts.state'; +import { StatusWrapper } from '../../../models/common.model'; diff --git a/src/app/models/common.model.ts b/src/app/models/common.model.ts index 8a4c3d35..4f93ac20 100644 --- a/src/app/models/common.model.ts +++ b/src/app/models/common.model.ts @@ -1,8 +1,16 @@ -import { Attachment } from "../services/models/mastodon.interfaces"; +import { Attachment, Status } from "../services/models/mastodon.interfaces"; +import { AccountInfo } from '../states/accounts.state'; export class OpenMediaEvent { constructor( public selectedIndex: number, public attachments: Attachment[]) { } +} + +export class StatusWrapper { + constructor( + public status: Status, + public provider: AccountInfo + ) { } } \ No newline at end of file diff --git a/src/app/services/tools.service.ts b/src/app/services/tools.service.ts index b07e8bde..1cf87b00 100644 --- a/src/app/services/tools.service.ts +++ b/src/app/services/tools.service.ts @@ -4,8 +4,7 @@ import { Store } from '@ngxs/store'; import { AccountInfo } from '../states/accounts.state'; import { MastodonService } from './mastodon.service'; import { Account, Results, Status } from "./models/mastodon.interfaces"; -import { StatusWrapper } from '../components/stream/stream.component'; - +import { StatusWrapper } from '../models/common.model'; @Injectable({ providedIn: 'root'