commit
18f6caf24a
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sengi",
|
||||
"version": "0.28.0",
|
||||
"version": "0.28.1",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "main-electron.js",
|
||||
"description": "A multi-account desktop client for Mastodon and Pleroma",
|
||||
|
@ -17,7 +17,7 @@ import { NotificationService } from '../../services/notification.service';
|
||||
import { StatusWrapper } from '../../models/common.model';
|
||||
import { AccountInfo } from '../../states/accounts.state';
|
||||
import { InstancesInfoService } from '../../services/instances-info.service';
|
||||
import { MediaService } from '../../services/media.service';
|
||||
import { MediaService, MediaWrapper } from '../../services/media.service';
|
||||
import { AutosuggestSelection, AutosuggestUserActionEnum } from './autosuggest/autosuggest.component';
|
||||
import { EmojiPickerComponent } from './emoji-picker/emoji-picker.component';
|
||||
import { PollEditorComponent } from './poll-editor/poll-editor.component';
|
||||
@ -79,8 +79,14 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
||||
|
||||
@Input('redraftedStatus')
|
||||
set redraftedStatus(value: StatusWrapper) {
|
||||
if (value) {
|
||||
if (value) {
|
||||
this.statusLoaded = false;
|
||||
|
||||
if(value.status && value.status.media_attachments){
|
||||
for (const m of value.status.media_attachments) {
|
||||
this.mediaService.addExistingMedia(new MediaWrapper(m.id, null, m));
|
||||
}
|
||||
}
|
||||
|
||||
const newLine = String.fromCharCode(13, 10);
|
||||
let content = value.status.content;
|
||||
|
@ -88,11 +88,11 @@ export class SearchComponent implements OnInit {
|
||||
})
|
||||
.then((results: Results) => {
|
||||
if (results) {
|
||||
this.accounts = results.accounts.slice(0, 5);
|
||||
this.accounts = results.accounts.slice(0, 7);
|
||||
this.hashtags = results.hashtags;
|
||||
|
||||
if(!this.hashtags.map(x => x.toLowerCase()).includes(data.toLowerCase())){
|
||||
this.hashtags.unshift(data);
|
||||
if(data && data[0] === '#' && !this.hashtags.map(x => x.toLowerCase()).includes(data.replace('#', '').toLowerCase())){
|
||||
this.hashtags.unshift(data.replace('#', ''));
|
||||
}
|
||||
|
||||
for (let status of results.statuses) {
|
||||
@ -107,6 +107,4 @@ export class SearchComponent implements OnInit {
|
||||
})
|
||||
.then(() => { this.isLoading = false; });
|
||||
}
|
||||
|
||||
private
|
||||
}
|
||||
|
@ -5,9 +5,10 @@
|
||||
<img class="notification-hub__notification--avatar" *ngIf="notification.avatar"
|
||||
src="{{ notification.avatar }}" />
|
||||
|
||||
<div class="notification-hub__notification--message">
|
||||
<div class="notification-hub__notification--message" [class.notification-hub__notification--message--no-avatar]="!notification.avatar">
|
||||
<span *ngIf="!notification.message">Error {{ notification.errorCode }}</span>
|
||||
<span *ngIf="notification.message">{{ notification.message }}</span>
|
||||
<span class="notification-hub__notification--count" *ngIf="notification.count > 1"> ({{ notification.count}})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -27,7 +27,17 @@
|
||||
}
|
||||
|
||||
&--message {
|
||||
padding-top: 4px;
|
||||
margin-left: 37px;
|
||||
|
||||
&--no-avatar {
|
||||
margin-left: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&--count {
|
||||
color: rgba(255, 255, 255, .6);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,17 +7,26 @@ import { NotificationService, NotificatioData } from '../../services/notificatio
|
||||
styleUrls: ['./notification-hub.component.scss']
|
||||
})
|
||||
export class NotificationHubComponent implements OnInit {
|
||||
notifications: NotificatioData[] = [];
|
||||
notifications: NotificationWrapper[] = [];
|
||||
|
||||
constructor(private notificationService: NotificationService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.notificationService.notifactionStream.subscribe((notification: NotificatioData) => {
|
||||
this.notifications.push(notification);
|
||||
let alreadyExistingNotification = this.notifications.find(x => x.avatar === notification.avatar && x.message === notification.message);
|
||||
|
||||
setTimeout(() => {
|
||||
this.notifications = this.notifications.filter(x => x.id !== notification.id);
|
||||
}, 5000);
|
||||
if(alreadyExistingNotification){
|
||||
alreadyExistingNotification.count++;
|
||||
} else{
|
||||
this.notifications.push(new NotificationWrapper(notification));
|
||||
if(this.notifications.length > 3){
|
||||
this.notifications.length = 3;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.notifications = this.notifications.filter(x => x.id !== notification.id);
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
//this.autoSubmit();
|
||||
@ -35,3 +44,11 @@ export class NotificationHubComponent implements OnInit {
|
||||
this.notifications = this.notifications.filter(x => x.id !== notification.id);
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationWrapper extends NotificatioData {
|
||||
constructor(data: NotificatioData) {
|
||||
super(data.avatar, data.errorCode, data.message, data.isError);
|
||||
}
|
||||
|
||||
count = 1;
|
||||
}
|
@ -11,6 +11,9 @@
|
||||
<ng-template contextMenuItem (execute)="copyStatusLink()" *ngIf="statusWrapper">
|
||||
Copy link to status
|
||||
</ng-template>
|
||||
<ng-template contextMenuItem (execute)="copyAllData()" *ngIf="statusWrapper">
|
||||
Copy all data
|
||||
</ng-template>
|
||||
<ng-template contextMenuItem divider="true" *ngIf="statusWrapper"></ng-template>
|
||||
<ng-template contextMenuItem (execute)="mentionAccount()" *ngIf="!isOwnerSelected">
|
||||
Mention @{{ this.username }}
|
||||
|
@ -75,7 +75,7 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
|
||||
|
||||
private checkStatus(accounts: AccountInfo[]): void {
|
||||
const selectedAccount = accounts.find(x => x.isSelected);
|
||||
|
||||
|
||||
this.isOwnerSelected = selectedAccount.username.toLowerCase() === this.displayedStatus.account.username.toLowerCase()
|
||||
&& selectedAccount.instance.toLowerCase() === this.displayedStatus.account.url.replace('https://', '').split('/')[0].toLowerCase();
|
||||
}
|
||||
@ -118,6 +118,33 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
|
||||
return false;
|
||||
}
|
||||
|
||||
copyAllData(): boolean {
|
||||
const newLine = String.fromCharCode(13, 10);
|
||||
|
||||
let selBox = document.createElement('textarea');
|
||||
selBox.style.position = 'fixed';
|
||||
selBox.style.left = '0';
|
||||
selBox.style.top = '0';
|
||||
selBox.style.opacity = '0';
|
||||
selBox.value = `${this.displayedStatus.url}${newLine}${newLine}${this.displayedStatus.content}${newLine}${newLine}`;
|
||||
|
||||
let parser = new DOMParser();
|
||||
var dom = parser.parseFromString(this.displayedStatus.content, 'text/html')
|
||||
selBox.value += `${dom.body.textContent}${newLine}${newLine}`;
|
||||
|
||||
for (const att of this.displayedStatus.media_attachments) {
|
||||
selBox.value += `${att.url}${newLine}${newLine}`;
|
||||
}
|
||||
|
||||
document.body.appendChild(selBox);
|
||||
selBox.focus();
|
||||
selBox.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(selBox);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
mentionAccount(): boolean {
|
||||
this.navigationService.replyToUser(this.fullHandle, false);
|
||||
return false;
|
||||
|
@ -12,6 +12,7 @@ import { NotificationService } from './notification.service';
|
||||
})
|
||||
export class MediaService {
|
||||
mediaSubject: BehaviorSubject<MediaWrapper[]> = new BehaviorSubject<MediaWrapper[]>([]);
|
||||
fileCache: { [url: string]: File } = {};
|
||||
|
||||
constructor(
|
||||
private readonly notificationService: NotificationService,
|
||||
@ -36,6 +37,7 @@ export class MediaService {
|
||||
|
||||
this.mastodonService.uploadMediaAttachment(account, file, null)
|
||||
.then((attachment: Attachment) => {
|
||||
this.fileCache[attachment.url] = file;
|
||||
let currentMedias = this.mediaSubject.value;
|
||||
let currentMedia = currentMedias.filter(x => x.id === uniqueId)[0];
|
||||
if (currentMedia) {
|
||||
@ -64,6 +66,15 @@ export class MediaService {
|
||||
});
|
||||
}
|
||||
|
||||
addExistingMedia(media: MediaWrapper){
|
||||
if(!this.fileCache[media.attachment.url]) return;
|
||||
|
||||
media.file = this.fileCache[media.attachment.url];
|
||||
let medias = this.mediaSubject.value;
|
||||
medias.push(media);
|
||||
this.mediaSubject.next(medias);
|
||||
}
|
||||
|
||||
remove(media: MediaWrapper) {
|
||||
let medias = this.mediaSubject.value;
|
||||
let filteredMedias = medias.filter(x => x.id !== media.id);
|
||||
@ -84,6 +95,7 @@ export class MediaService {
|
||||
for (let media of medias) {
|
||||
this.mastodonService.uploadMediaAttachment(account, media.file, media.description)
|
||||
.then((attachment: Attachment) => {
|
||||
this.fileCache[attachment.url] = media.file;
|
||||
let currentMedias = this.mediaSubject.value;
|
||||
let currentMedia = currentMedias.filter(x => x.id === media.id)[0];
|
||||
if (currentMedia) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user