diff --git a/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.html b/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.html
index 3b49e8a7..8e252e49 100644
--- a/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.html
+++ b/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.html
@@ -27,7 +27,13 @@
Unmute conversation
-
+
+ Hide boosts from @{{ this.username }}
+
+
+ Unhide boosts from @{{ this.username }}
+
+
Mute @{{ this.username }}
@@ -40,6 +46,14 @@
Unblock @{{ this.username }}
+
+
+ Block domain {{ this.domain }}
+
+
+ Unblock domain {{ this.domain }}
+
+
Pin on profile
diff --git a/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.ts b/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.ts
index f09e1cf4..20bb9a5b 100644
--- a/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.ts
+++ b/src/app/components/stream/status/action-bar/status-user-context-menu/status-user-context-menu.component.ts
@@ -25,6 +25,7 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
private loadedAccounts: AccountInfo[];
displayedStatus: Status;
username: string;
+ domain: string;
isOwnerSelected: boolean;
isEditingAvailable: boolean;
@@ -74,6 +75,7 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
}
this.username = account.acct.split('@')[0];
+ this.domain = account.acct.split('@')[1];
this.fullHandle = this.toolsService.getAccountFullHandle(account);
}
@@ -167,6 +169,38 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
return false;
}
+ hideBoosts(): boolean {
+ const acc = this.toolsService.getSelectedAccounts()[0];
+
+ this.toolsService.findAccount(acc, this.fullHandle)
+ .then(async (target: Account) => {
+ const relationship = await this.mastodonService.hideBoosts(acc, target);
+ this.relationship = relationship;
+ this.relationshipChanged.next(relationship);
+ })
+ .catch(err => {
+ this.notificationService.notifyHttpError(err, acc);
+ });
+
+ return false;
+ }
+
+ unhideBoosts(): boolean {
+ const acc = this.toolsService.getSelectedAccounts()[0];
+
+ this.toolsService.findAccount(acc, this.fullHandle)
+ .then(async (target: Account) => {
+ const relationship = await this.mastodonService.unhideBoosts(acc, target);
+ this.relationship = relationship;
+ this.relationshipChanged.next(relationship);
+ })
+ .catch(err => {
+ this.notificationService.notifyHttpError(err, acc);
+ });
+
+ return false;
+ }
+
muteAccount(): boolean {
const acc = this.toolsService.getSelectedAccounts()[0];
@@ -241,6 +275,37 @@ export class StatusUserContextMenuComponent implements OnInit, OnDestroy {
return false;
}
+ blockDomain(): boolean {
+ const response = confirm(`Are you really sure you want to block the entire ${this.domain} domain? You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.`);
+
+ if (response) {
+ const acc = this.toolsService.getSelectedAccounts()[0];
+
+ this.mastodonService.blockDomain(acc, this.domain)
+ .then(_ => {
+ this.relationship.domain_blocking = true;
+ })
+ .catch(err => {
+ this.notificationService.notifyHttpError(err, acc);
+ });
+ }
+ return false;
+ }
+
+ unblockDomain(): boolean {
+ const acc = this.toolsService.getSelectedAccounts()[0];
+
+ this.mastodonService.blockDomain(acc, this.domain)
+ .then(_ => {
+ this.relationship.domain_blocking = false;
+ })
+ .catch(err => {
+ this.notificationService.notifyHttpError(err, acc);
+ });
+
+ return false;
+ }
+
muteConversation(): boolean {
const selectedAccount = this.toolsService.getSelectedAccounts()[0];
diff --git a/src/app/services/mastodon-wrapper.service.ts b/src/app/services/mastodon-wrapper.service.ts
index 38717d37..d33517b8 100644
--- a/src/app/services/mastodon-wrapper.service.ts
+++ b/src/app/services/mastodon-wrapper.service.ts
@@ -22,14 +22,14 @@ export class MastodonWrapperService {
private readonly mastodonService: MastodonService) { }
refreshAccountIfNeeded(accountInfo: AccountInfo): Promise {
- if(this.refreshingToken[accountInfo.id]){
+ if (this.refreshingToken[accountInfo.id]) {
return this.refreshingToken[accountInfo.id];
}
let isExpired = false;
let storedAccountInfo = this.getStoreAccountInfo(accountInfo.id);
- if(!storedAccountInfo || !(storedAccountInfo.token))
+ if (!storedAccountInfo || !(storedAccountInfo.token))
return Promise.resolve(accountInfo);
try {
@@ -96,7 +96,7 @@ export class MastodonWrapperService {
return this.mastodonService.getInstance(instance);
}
- translate(account: AccountInfo, statusId: string, lang: string): Promise{
+ translate(account: AccountInfo, statusId: string, lang: string): Promise {
return this.refreshAccountIfNeeded(account)
.then((refreshedAccount: AccountInfo) => {
return this.mastodonService.translate(refreshedAccount, statusId, lang);
@@ -146,7 +146,7 @@ export class MastodonWrapperService {
}
search(account: AccountInfo, query: string, version: 'v1' | 'v2', resolve: boolean = false): Promise {
- if(query.includes('twitter.com')){
+ if (query.includes('twitter.com')) {
query = this.processTwitterQuery(query);
}
@@ -158,17 +158,17 @@ export class MastodonWrapperService {
private processTwitterQuery(query: string): string {
const settings = this.settingsService.getSettings();
- if(!settings.twitterBridgeInstance) return query;
+ if (!settings.twitterBridgeInstance) return query;
let name;
- if(query.includes('twitter.com/')){
+ if (query.includes('twitter.com/')) {
console.log(query.replace('https://', '').replace('http://', '').split('/'));
name = query.replace('https://', '').replace('http://', '').split('/')[1];
}
- if(query.includes('@twitter.com')){
+ if (query.includes('@twitter.com')) {
console.log(query.split('@'));
name = query.split('@')[0];
- if(name === '' || name == null){
+ if (name === '' || name == null) {
name = query.split('@')[1];
}
}
@@ -208,7 +208,7 @@ export class MastodonWrapperService {
}
searchAccount(account: AccountInfo, query: string, limit: number = 40, following: boolean = false, resolve = true): Promise {
- if(query.includes('twitter.com')){
+ if (query.includes('twitter.com')) {
query = this.processTwitterQuery(query);
}
@@ -281,6 +281,20 @@ export class MastodonWrapperService {
});
}
+ hideBoosts(currentlyUsedAccount: AccountInfo, account: Account): Promise {
+ return this.refreshAccountIfNeeded(currentlyUsedAccount)
+ .then((refreshedAccount: AccountInfo) => {
+ return this.mastodonService.hideBoosts(refreshedAccount, account);
+ });
+ }
+
+ unhideBoosts(currentlyUsedAccount: AccountInfo, account: Account): Promise {
+ return this.refreshAccountIfNeeded(currentlyUsedAccount)
+ .then((refreshedAccount: AccountInfo) => {
+ return this.mastodonService.unhideBoosts(refreshedAccount, account);
+ });
+ }
+
followHashtag(currentlyUsedAccount: AccountInfo, hashtag: string): Promise {
return this.refreshAccountIfNeeded(currentlyUsedAccount)
.then((refreshedAccount: AccountInfo) => {
@@ -407,6 +421,20 @@ export class MastodonWrapperService {
});
}
+ blockDomain(account: AccountInfo, domain: string): Promise {
+ return this.refreshAccountIfNeeded(account)
+ .then((refreshedAccount: AccountInfo) => {
+ return this.mastodonService.blockDomain(refreshedAccount, domain);
+ });
+ }
+
+ unblockDomain(account: AccountInfo, domain: string): Promise {
+ return this.refreshAccountIfNeeded(account)
+ .then((refreshedAccount: AccountInfo) => {
+ return this.mastodonService.unblockDomain(refreshedAccount, domain);
+ });
+ }
+
pinOnProfile(account: AccountInfo, statusId: string): Promise {
return this.refreshAccountIfNeeded(account)
.then((refreshedAccount: AccountInfo) => {
@@ -470,14 +498,14 @@ export class MastodonWrapperService {
});
}
- getFollowing(account: AccountInfo, accountId: number, maxId: string, sinceId: string, limit: number = 40): Promise {
+ getFollowing(account: AccountInfo, accountId: number, maxId: string, sinceId: string, limit: number = 40): Promise {
return this.refreshAccountIfNeeded(account)
.then((refreshedAccount: AccountInfo) => {
return this.mastodonService.getFollowing(refreshedAccount, accountId, maxId, sinceId, limit);
});
}
- getFollowers(account: AccountInfo, accountId: number, maxId: string, sinceId: string, limit: number = 40): Promise {
+ getFollowers(account: AccountInfo, accountId: number, maxId: string, sinceId: string, limit: number = 40): Promise {
return this.refreshAccountIfNeeded(account)
.then((refreshedAccount: AccountInfo) => {
return this.mastodonService.getFollowers(refreshedAccount, accountId, maxId, sinceId, limit);
diff --git a/src/app/services/mastodon.service.ts b/src/app/services/mastodon.service.ts
index e4ce63b2..cc69ce0f 100644
--- a/src/app/services/mastodon.service.ts
+++ b/src/app/services/mastodon.service.ts
@@ -357,6 +357,26 @@ export class MastodonService {
}
+ hideBoosts(currentlyUsedAccount: AccountInfo, account: Account): Promise {
+ const route = `https://${currentlyUsedAccount.instance}${this.apiRoutes.follow}`.replace('{0}', account.id.toString());
+ const headers = new HttpHeaders({ 'Authorization': `Bearer ${currentlyUsedAccount.token.access_token}` });
+
+ let input = new FormData();
+ input.append('reblogs', 'false');
+
+ return this.httpClient.post(route, input, { headers: headers }).toPromise();
+ }
+
+ unhideBoosts(currentlyUsedAccount: AccountInfo, account: Account): Promise {
+ const route = `https://${currentlyUsedAccount.instance}${this.apiRoutes.follow}`.replace('{0}', account.id.toString());
+ const headers = new HttpHeaders({ 'Authorization': `Bearer ${currentlyUsedAccount.token.access_token}` });
+
+ let input = new FormData();
+ input.append('reblogs', 'true');
+
+ return this.httpClient.post(route, input, { headers: headers }).toPromise();
+ }
+
followHashtag(currentlyUsedAccount: AccountInfo, hashtag: string): Promise {
const route = `https://${currentlyUsedAccount.instance}${this.apiRoutes.followHashtag}`.replace('{0}', hashtag);
const headers = new HttpHeaders({ 'Authorization': `Bearer ${currentlyUsedAccount.token.access_token}` });
@@ -524,6 +544,23 @@ export class MastodonService {
return this.httpClient.post(route, null, { headers: headers }).toPromise();
}
+ blockDomain(account: AccountInfo, domain: string): Promise {
+ let route = `https://${account.instance}${this.apiRoutes.blockDomain}`;
+ const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
+
+ let input = new FormData();
+ input.append('domain', domain);
+
+ return this.httpClient.post(route, input, { headers: headers }).toPromise();
+ }
+
+ unblockDomain(account: AccountInfo, domain: string): Promise {
+ let route = `https://${account.instance}${this.apiRoutes.blockDomain}?domain=${domain}`;
+ const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}`});
+
+ return this.httpClient.delete(route, { headers: headers }).toPromise();
+ }
+
pinOnProfile(account: AccountInfo, statusId: string): Promise {
let route = `https://${account.instance}${this.apiRoutes.pinStatus}`.replace('{0}', statusId.toString());
const headers = new HttpHeaders({ 'Authorization': `Bearer ${account.token.access_token}` });
diff --git a/src/app/services/models/api.settings.ts b/src/app/services/models/api.settings.ts
index 3a204317..6a36c09f 100644
--- a/src/app/services/models/api.settings.ts
+++ b/src/app/services/models/api.settings.ts
@@ -12,6 +12,7 @@ export class ApiRoutes {
unfollow = '/api/v1/accounts/{0}/unfollow';
block = '/api/v1/accounts/{0}/block';
unblock = '/api/v1/accounts/{0}/unblock';
+ blockDomain = '/api/v1/domain_blocks';
mute = '/api/v1/accounts/{0}/mute';
unmute = '/api/v1/accounts/{0}/unmute';
muteStatus = '/api/v1/statuses/{0}/mute';