displaying autosuggestions #127
This commit is contained in:
parent
0d44668b7a
commit
65f2154ea1
|
@ -63,6 +63,7 @@ import { ListEditorComponent } from './components/floating-column/manage-account
|
|||
import { ListAccountComponent } from './components/floating-column/manage-account/my-account/list-editor/list-account/list-account.component';
|
||||
import { PollComponent } from './components/stream/status/poll/poll.component';
|
||||
import { TimeLeftPipe } from './pipes/time-left.pipe';
|
||||
import { AutosuggestComponent } from './components/create-status/autosuggest/autosuggest.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", redirectTo: "home", pathMatch: "full" },
|
||||
|
@ -113,7 +114,8 @@ const routes: Routes = [
|
|||
ListEditorComponent,
|
||||
ListAccountComponent,
|
||||
PollComponent,
|
||||
TimeLeftPipe
|
||||
TimeLeftPipe,
|
||||
AutosuggestComponent
|
||||
],
|
||||
imports: [
|
||||
FontAwesomeModule,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<div class="autosuggest">
|
||||
<div *ngFor="let a of accounts" class="autosuggest__entry autosuggest__account">
|
||||
<img class="autosuggest__account--avatar" src="{{ a.avatar }}" /> {{ a.username }} @{{ a.acct }}
|
||||
</div>
|
||||
|
||||
<div *ngFor="let h of hashtags" class="autosuggest__entry">
|
||||
#{{ h }}
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,10 @@
|
|||
.autosuggest {
|
||||
&__entry {}
|
||||
|
||||
&__account {
|
||||
&--avatar {
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AutosuggestComponent } from './autosuggest.component';
|
||||
|
||||
xdescribe('AutosuggestComponent', () => {
|
||||
let component: AutosuggestComponent;
|
||||
let fixture: ComponentFixture<AutosuggestComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AutosuggestComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AutosuggestComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,66 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
import { MastodonService } from '../../../services/mastodon.service';
|
||||
import { NotificationService } from '../../../services/notification.service';
|
||||
import { Results, Account } from '../../../services/models/mastodon.interfaces';
|
||||
|
||||
@Component({
|
||||
selector: 'app-autosuggest',
|
||||
templateUrl: './autosuggest.component.html',
|
||||
styleUrls: ['./autosuggest.component.scss']
|
||||
})
|
||||
export class AutosuggestComponent implements OnInit {
|
||||
accounts: Account[] = [];
|
||||
hashtags: string[] = [];
|
||||
|
||||
private _pattern: string;
|
||||
@Input('pattern')
|
||||
set pattern(value: string) {
|
||||
this._pattern = value;
|
||||
this.analysePattern(value);
|
||||
}
|
||||
get pattern(): string {
|
||||
return this._pattern;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly toolsService: ToolsService,
|
||||
private readonly mastodonService: MastodonService) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
private lastPatternUsed: string;
|
||||
private analysePattern(value: string) {
|
||||
const selectedAccount = this.toolsService.getSelectedAccounts()[0];
|
||||
const isAccount = value[0] === '@';
|
||||
const pattern = value.substring(1);
|
||||
this.lastPatternUsed = pattern;
|
||||
|
||||
this.mastodonService.search(selectedAccount, pattern, false)
|
||||
.then((results: Results) => {
|
||||
if(this.lastPatternUsed !== pattern) return;
|
||||
|
||||
this.accounts.length = 0;
|
||||
this.hashtags.length = 0;
|
||||
|
||||
if (isAccount) {
|
||||
for (let account of results.accounts) {
|
||||
this.accounts.push(account);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let hashtag of results.hashtags) {
|
||||
if (hashtag.includes(this.lastPatternUsed) || hashtag === this.lastPatternUsed) {
|
||||
this.hashtags.push(hashtag);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.notificationService.notifyHttpError(err);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -10,8 +10,9 @@
|
|||
class="form-control form-control-sm status-form__status flexcroll" rows="5" required title="content"
|
||||
placeholder="What's in your mind?" (keydown.control.enter)="onCtrlEnter()"></textarea>
|
||||
|
||||
<div class="status-form__mention-error" *ngIf="mentionTooFarAwayError">Error: mentions must be placed closer to the
|
||||
start in order to use multiposting.</div>
|
||||
<app-autosuggest *ngIf="autosuggestData" [pattern]="autosuggestData"></app-autosuggest>
|
||||
|
||||
<div class="status-form__mention-error" *ngIf="mentionTooFarAwayError">Error: mentions must be placed closer to the start in order to use multiposting.</div>
|
||||
|
||||
<select class="form-control form-control-sm form-control--privacy" id="privacy" name="privacy"
|
||||
[(ngModel)]="selectedPrivacy">
|
||||
|
|
|
@ -11,7 +11,6 @@ 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 { identifierModuleUrl } from '@angular/compiler';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -34,6 +33,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
set status(value: string) {
|
||||
if (value) {
|
||||
this.countStatusChar(value);
|
||||
this.detectAutosuggestion(value);
|
||||
this._status = value;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
postCounts: number = 1;
|
||||
isSending: boolean;
|
||||
mentionTooFarAwayError: boolean;
|
||||
autosuggestData: string = null;
|
||||
|
||||
@Input() statusReplyingToWrapper: StatusWrapper;
|
||||
@Output() onClose = new EventEmitter();
|
||||
|
@ -163,6 +164,19 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
this.accountSub.unsubscribe();
|
||||
}
|
||||
|
||||
private detectAutosuggestion(status: string) {
|
||||
const parsedStatus = status.split(' ');
|
||||
if(parsedStatus && parsedStatus.length > 0){
|
||||
const lastElement = parsedStatus[parsedStatus.length - 1];
|
||||
if(lastElement.length > 2 && (lastElement.startsWith('@') || lastElement.startsWith('#'))){
|
||||
//this.autosuggestData = lastElement.substring(1);
|
||||
this.autosuggestData = lastElement;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.autosuggestData = null;
|
||||
}
|
||||
|
||||
private focus() {
|
||||
setTimeout(() => {
|
||||
this.replyElement.nativeElement.focus();
|
||||
|
|
Loading…
Reference in New Issue