1. Anleitung zur Bedienung

Die Website bietet momentan 2 Dienste,

  • Mitmachgeschichten

  • und Bildbearbeitung

homescreen

Wenn man nun über die Felder mit der Maus fährt, werden diese mit einer Farbe umrandet. Klickt man nun auf ein Bild, wechselt man zur dementsprechenden Seite. Hierbei ist die Maus auf der linken Seite geklickt worden, daraufhin gelangt man zur Übersichtsseite der Mitmachgeschichten.

leereMitmachGeschichten

In diesem Fall gibt es noch keine Mitmachgeschichten, um eine anzulegen muss man auf den rot umrandeten Button klicken.

mmgStart

Nun ist man auf einer neuen Seite, auf welcher man Geschichten erstellen kann. Dazu kann man zuerst ein Titelbild (Button im rot umrandeten Kästchen klicken) hochladen. Anschließend kann man eine Maske für eine Scene erstellen, dazu den Button im gelben Kasten klicken.

mmgTeilscene1

Nach dem Klick des Buttons poppt die Maske auf. Sie beinhaltet ein Textfeld (rot umrandet), dieser Text wird dann auch vom Pepper ausgegeben. Dazu einfach in das Textfeld klicken und losschreiben. Anschließend kann man die Bewegung zu der Scene auswählen. Hierführ auf den Kasten im gelb umrandeten klicken, und die passende Bewegung aussuchen.

mmgTeilscene2

Daraufhin kann man auch die Zeitdauer der Scene / Bewegung anpassen. Hierführ auf das im rot umrandeten Kasten klicken. Um ein Bild zu der Scene hinzufügen zu können, muss man auf das Feld (gelber Kasten) klicken, oder es per Drag and Drop einfach in das Feld hineinziehen. Fertig ist eine Scene!

mmgBildLöschen

Falls man jedoch ein falsches Bild hochgeladen hat, kann man auf dem im rot umrandeten Button im Kasten klicken. Daraufhin folgt eine Sicherheitsfrage, falls man doch unabsichtlich auf den Button gekommen ist. Im gelben Kasten markiert kann man dann seine Auswahl treffen.

mmgSceneLöschen

Der Mistkübel ganz rechts (rot umrandet) macht dasselbe wie zuvor genannt, jedoch aber für die ganze Scene. Als Sicherheitsfrage poppt wieder ein Fenster auf, wo man im (gelben Kasten markiert) seine Antwort treffen kann.

mmgSpeichern
  • Falls man die Reihenfolge einzelner Scenen ändern möchte, genügt es eine Scene mit der linken Maustaste zu halten, und diese dann an die gewünschte Position zu ziehen. (In kein explizites Feld der Scene klicken, sondern auf einen leeren Platz, wie zum Beispiel auf das Symbol in der oberen linken Ecke)

Wenn man nun seine Geschichte fertig gebaut hat, kann man sie ganz einfach speichern, indem man auf den Button im rot umrandeten Kasten klickt. Nach einer kurzen Ladezeit kommt man wieder auf die Mitmachgeschichten-Übersichtsseite, wo dann die gerade erstellte Geschichte mit dem Titelnamen angezeigt wird.

mmg1Geschichte

Nach gleichem Ablauf kann man so beliebig viele Gesichten erstellen, zur Veranschaulichung wurde eine zweite Geschichte erstellt.

mmg2Geschichten
mmgBearbeiten

Falls man nun eine Geschichte nochmal überarbeiten möchte, muss man lediglich auf das Symbol im roten Kasten klicken, und nach kurzer Ladezeit wird die Geschichte angezeigt. Wenn die Änderungen durchgeführt worden sind, muss nur der Geschichte speichern Button oben rechts geklickt werden, und man gelangt wieder zur Übersichtsseite zurück.

mmgLöschen

Falls eine Geschichte nicht mehr erwünscht ist, muss man auf den Mistkübel (rot umrandet) klicken. Anschließend wird wieder eine Sicherheitsabfrage erscheinen, wo man wieder mit den Buttons (im gelb umrandeten Kasten) antworten kann.

mmgFilter

Hat man schließlich mehrere Geschichten und möchte nach einer bestimmten Geschichte suchen, kann man in das Suchfeld (im roten Kasten) das gewünschte Filterkriterium schreiben. Es werden dann nur Geschichten angezeigt, bei welchen der Text im Titelnamen vorkommt.

mmgZurück

Hat man nun alles erledigt, und möchte zum Homescreen zurückkehren, muss man auf den Inhalt des rot markierten Kasten drücken, und man wechselt zurück zum Homescreen.

homescreen

Jetzt ist man auf dem Homescreen zurück und bewegt den Mauszeiger nach rechts zum Teil Bilder. Wenn man mit der Maus drüber fährt erscheint eine rote Umrandung.

pictureScreenAlleFilter

Nach dem Klick auf das Feld wo Bilder oben steht, kommt man auf die Seite die oben im Bild zu sehen ist wo es eine Übersicht über alle gespeicherten Bilder zu sehen gibt. Man sieht 3 Knöpfe die für einen Filter sind, der je nach Klick entweder Alle Bilder, Personenbezogene Bilder, oder Bilder für die Mitmachengeschichten anzeigt. Welcher Filter aktiv ist, sieht man an der hellblauen Hervorhebung.

pictureScreenPersonFilter

Jetzt ist der Personen Filter aktiv, momentan sind aber keine Bilder die Personenbezogen sind enthalten.

pictureScreenMmgFilter

An der Hervorhebung erkennt man das gerade der Mitmachgeschichten Filter aktiv ist.

pictureUploadButton

Wenn man jetzt oben auf den Knopf Neues Bild Hinzufügen drückt, welcher im roten Kasten markiert ist kommt man auf die nächste Seite.

bildEditorScreen

Auf dieser Seite kann man Bilder hinzufügen die für Mitmachgeschichten und später auch für die Minigames verwendet werden können, wenn Personenbezogene Bilder hinzugefügt werden.

uploadButton

Bilder werden eingefügt indem man in den roten Kasten reindrückt, oder ein Bild in den roten Kasten reingefügt wird.

fileSystemPictures

Wenn in den roten Kasten gedrückt wurde, wird Ihr File-System geöffnet, von dem Sie die Bilder hochladen können.

pictureUploaded

Jetzt ist ein Bild ausgewählt und es wird in dem Feld, das davor als Platzhalter Grau war, angezeigt. Man sieht so ein kleines Grid in dem Bild, das ist das was in der Dimension vom Pepper (1280x800) rausgeschnitten und gespeichert wird. In dem Minifenster kann man reinzoomen, oder man verwendet den Blauen Slider unten.

littlePicture

Wenn ein etwas kleineres Bild, welches von den Dimensionen so klein ist, ausgewählt wurde kommt eine Warnung, dass das Bild kleiner ist und der Slider eventuell nicht ganz richtig funktioniert, der Rest funktioniert ganz normal.

descriptionButton

Um ein Bild vollständig zu Speichern muss eine Bezeichnung eingegeben werden. Wenn dies nicht passiert wird das Bild nicht gespeichert, bis eine Beschreibung eingegeben wurde. Wenn es vollständig gespeichert wurde, dann ladet sich die Seite neu.

resetButton

Wenn auf den Zurücksetzen Knopf gedrückt wird, der blau hinterlegt ist wenn man darüber fährt, wird das Bild in seine Ursprüngliche Lage geladen, falls einem die skalierungen nicht gefallen die durchgeführt wurden.

downloadPicButton

Der Bild Herunterladen Knopf wird ebenfalls Blau hinterlegt wenn die Maus drüber gefahren wird. Der Button lädt das Bild in seinem bearbeitetem Zustand herunter, damit man das dann auswählen kann und dieses Bild dann verwendet.

showRecommendations

Man kann sich inspirieren lassen, wie man das Bild zuschneiden könnte, indem man in das Rot markierte Feld reindrückt, dann sieht man schon unten ein Paar Vorschläge, wenn drauf gedrückt wird, passiert dasselbe wie mein Bild Herunterladen Knopf. Bei einem erneuten klick auf den Knopf werden die Vorschläge wieder eingeklappt.

savePicture

Wenn man mit dem Bild zufrieden ist und eine Bezeichnung eingegeben hat, drückt man auf den Blauen Knopf, der Rot markiert ist und auf dem steht Bild Speichern, wodurch das Bild in die Datenbank gespeichert wird und die Seite neugeladen wird, bei einem erfolgreichem Speichern.

hochladenCancel

Zuletzt gibt es noch den Hochladen Abbrechen Knopf, der grad Rot markiert ist, welcher den Vorgang einfach abbricht und die Seite neu ladet.

Auf die Hompage kommt man indem man wie vorhin schon erwähnt worden ist, oben auf Pepper Dashboard klickt.

2. Schnittstellenbeschreibung IST

storys.service.ts
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { STORY_URL } from './app.config';
import { Observable } from 'rxjs';


export interface Storys {
  id: number
  name: string
  storyIcon: string
  steps: Step[]
  isEnabled: boolean
}

export interface Step {
  id: number
  text: string
  image: string
  duration: number
  moveNameAndDuration: string
}

@Injectable({
  providedIn: 'root'
})
export class StorysService {
  constructor(private httpClient: HttpClient, @Inject(STORY_URL) private baseUrl: string) { }

  getTagalongstories(): Observable<Storys[]> {
    return this.httpClient.get<Storys[]>(this.baseUrl);
  }

  postgetTagalongstories(story: Storys): Observable<Storys> {
    return this.httpClient.post<Storys>(this.baseUrl, story);
  }

  getTagalongstory(id: number): Observable<Storys> {
    return this.httpClient.get<Storys>(`${this.baseUrl}/${id}`);
  }

  putTagalongstory(story: Storys): Observable<Storys> {
    return this.httpClient.put<Storys>(`${this.baseUrl}/${story.id}`, story);
  }

  deleteTagalongstory(id: number): Observable<Storys> {
    return this.httpClient.delete<Storys>(`${this.baseUrl}/${id}`);
  }

  postTagalongstorySteps(id: number): Observable<Step> {
    return this.httpClient.post<Step>(`${this.baseUrl}/${id}/steps`, id);
  }

  getTagalongstorySteps(id: number): Observable<Step[]> {
    return this.httpClient.get<Step[]>(`${this.baseUrl}/${id}/steps`);
  }

}
Bitte im endgültigen Produkt anstelle "Storys" bitte "Stories" verwenden.

2.1. Speichern der Images

  • Von Angular werden die Images als base64-codierter String übergeben.

    • zB data:image/jpeg;base64,/9j/4U6aRXhpZgAA…​

    • Im Legacy-Service wird dieser String als byte[] gespeichert.

    • Zusätzlich wird noch der Image-Typ gespeichert (zB "image/jpeg").

Beim Upload auf Images einschränken. Derzeit könnten auch Videos und andere Formate hochgeladen werden.

2.2. Endpoint: Auflisten aller Stories

  • implementiert

typescript code
getTagalongstories(): Observable<Storys[]> {
return this.httpClient.get<Storys[]>(this.baseUrl);
}
verwendete Datenstruktur
export interface Storys {
  id: number
  name: string
  storyIcon: string
  steps: Step[]
  isEnabled: boolean
}

export interface Step {
  id: number
  text: string
  image: string
  duration: number
  moveNameAndDuration: string
}
request
GET http://localhost:8080/api/legacy/stories
Accept: application/json
response
[
  {
    "id": 2,
    "name": "Geschichten aus Vorarlberg",
    "icon": "null",
    "steps": [
      {
        "id": 1,
        "text": "GAME ID 2",
        "image": "n/a",
        "duration": 10,
        "moveNameAndDuration": "emote_hurra"
      },
      {
        "id": 3,
        "text": "GAME ID 2",
        "image": "n/a",
        "duration": 5,
        "moveNameAndDuration": "gehen"
      }
    ],
    "isEnabled": true
  }
]

2.3. Endpoint: Erstellen einer Story

  • implementiert

typescript code
postgetTagalongstories(story: Storys): Observable<Storys> {
  return this.httpClient.post<Storys>(this.baseUrl, story);
}

Frage: warum heißt die Methode postget…​ und nicht post…​?

request
POST http://localhost:8080/api/legacy/stories
Content-Type: application/json

{
  "name": "dddddd",
  "id": 0,
  "isEnabled": true,
  "steps": [
    {
      "id": 0,
      "text": "asdf",
      "duration": 15,
      "moveNameAndDuration": "highfive_links"
    }
  ]
}
moveNameAndDuration: Dieses Feld wurde inhaltlich verändert, da die Duration nun weggelassen wird (highfive_links statt highfive_links_15).

2.4. Endpoint: Abrufen einer Story durch Story-Id

  • implementiert

  • Parameter

    • Story-id als PathParam

  • Response

    • Location-URI

    • zB

      HTTP/1.1 201 Created
      Location: http://localhost:8080/api/legacy/stories/4
typescript code
getTagalongstory(id: number): Observable<Storys> {
  return this.httpClient.get<Storys>(`${this.baseUrl}/${id}`);
}
request
GET http://localhost:8080/api/legacy/stories/1
Accept: application/json

2.5. Endpoint: Ändern einer Story

  • implementiert (teilweise - Ändern der Steps fehlt noch, sowie Reihenfolge der Steps)

  • Parameter

    • Story-id als PathParam

    • Story-Object im Body

typescript code
putTagalongstory(story: Storys): Observable<Storys> {
  return this.httpClient.put<Storys>(`${this.baseUrl}/${story.id}`, story);
}
request
PUT http://localhost:8080/api/legacy/stories/1
Accept: application/json

// Story als Json-Object ...

2.6. Endpoint: Löschen einer Story

  • implementiert

  • Parameter

    • Story-id als PathParam

typescript code
deleteTagalongstory(id: number): Observable<Storys> {
  return this.httpClient.delete<Storys>(`${this.baseUrl}/${id}`);
}
request
DELETE http://localhost:8080/api/legacy/stories/1
Accept: application/json

2.7. Endpoint: Erstellen von Steps

  • NICHT implementiert

  • Die Anforderungen sind hier nicht klar.

    • es wird kein Step Objekt übergeben

2.8. Endpoint: Abrufen von Steps

  • NICHT implementiert

3. Datenmodell SOLL

3.1. Klassendiagramm

cld

3.2. ERD

erd