removed all table-mode stuff, minor ui tweaks
* changed all icons to 48dp * the choisBox in SeriesView is now readable
|
@ -38,7 +38,6 @@ import java.util.ResourceBundle;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -51,31 +50,21 @@ import com.jfoenix.controls.JFXButton;
|
|||
import com.jfoenix.controls.JFXColorPicker;
|
||||
import com.jfoenix.controls.JFXHamburger;
|
||||
import com.jfoenix.controls.JFXSlider;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import com.jfoenix.controls.JFXToggleButton;
|
||||
import com.jfoenix.transitions.hamburger.HamburgerBackArrowBasicTransition;
|
||||
|
||||
import javafx.animation.TranslateTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeTableColumn;
|
||||
import javafx.scene.control.TreeTableColumn.SortType;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
import javafx.scene.effect.BoxBlur;
|
||||
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
|
@ -83,9 +72,6 @@ import javafx.scene.layout.HBox;
|
|||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.FontWeight;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.text.TextFlow;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
@ -101,21 +87,23 @@ import kellerkinder.HomeFlix.player.Player;
|
|||
|
||||
public class MainWindowController {
|
||||
|
||||
// general/settings fxml elements
|
||||
// general
|
||||
@FXML private AnchorPane mainAnchorPane;
|
||||
@FXML private ScrollPane settingsScrollPane;
|
||||
|
||||
@FXML private JFXHamburger menuHam;
|
||||
@FXML private HBox topHBox;
|
||||
@FXML private VBox sideMenuVBox;
|
||||
@FXML private TableView<SourceDataType> sourcesTable;
|
||||
|
||||
@FXML private JFXHamburger menuHam;
|
||||
|
||||
@FXML private JFXButton aboutBtn;
|
||||
@FXML private JFXButton settingsBtn;
|
||||
|
||||
// settings
|
||||
@FXML private ScrollPane settingsScrollPane;
|
||||
|
||||
@FXML private JFXButton updateBtn;
|
||||
@FXML private JFXButton addDirectoryBtn;
|
||||
@FXML private JFXButton addStreamSourceBtn;
|
||||
|
||||
@FXML private JFXToggleButton autoUpdateToggleBtn;
|
||||
@FXML private JFXToggleButton autoplayToggleBtn;
|
||||
|
||||
|
@ -135,32 +123,11 @@ public class MainWindowController {
|
|||
@FXML private Label sourcesLbl;
|
||||
@FXML private Label versionLbl;
|
||||
|
||||
@FXML private TableView<SourceDataType> sourcesTable;
|
||||
@FXML private TreeItem<SourceDataType> sourceRoot = new TreeItem<>(new SourceDataType("", ""));
|
||||
@FXML private TableColumn<SourceDataType, String> sourceColumn;
|
||||
@FXML private TableColumn<SourceDataType, String> modeColumn;
|
||||
|
||||
// table-mode
|
||||
@FXML private AnchorPane tableModeAnchorPane;
|
||||
@FXML private JFXTextField searchTextField;
|
||||
|
||||
@FXML private TreeTableView<FilmTabelDataType> filmsTreeTable;
|
||||
@FXML private TreeTableColumn<FilmTabelDataType, String> columnStreamUrl;
|
||||
@FXML private TreeTableColumn<FilmTabelDataType, String> columnTitle;
|
||||
@FXML private TreeTableColumn<FilmTabelDataType, ImageView> columnFavorite;
|
||||
@FXML private TreeTableColumn<FilmTabelDataType, String> columnSeason;
|
||||
@FXML private TreeTableColumn<FilmTabelDataType, String> columnEpisode;
|
||||
@FXML private TreeItem<FilmTabelDataType> filmRoot = new TreeItem<>(new FilmTabelDataType("", "", "", "", false, null));
|
||||
|
||||
|
||||
@FXML private ScrollPane textScrollPane;
|
||||
@FXML private TextFlow textFlow;
|
||||
@FXML private ImageView posterImageView;
|
||||
|
||||
@FXML private JFXButton playbtn;
|
||||
@FXML private JFXButton openfolderbtn;
|
||||
@FXML private JFXButton returnBtn;
|
||||
@FXML private JFXButton forwardBtn;
|
||||
|
||||
// poster-mode
|
||||
@FXML private ScrollPane posterModeScrollPane;
|
||||
@FXML private FlowPane posterModeFlowPane;
|
||||
|
@ -177,27 +144,18 @@ public class MainWindowController {
|
|||
|
||||
private boolean menuTrue = false;
|
||||
|
||||
private final String version = "0.7.0";
|
||||
private final String buildNumber = "169";
|
||||
private final String version = "0.7.90";
|
||||
private final String buildNumber = "171";
|
||||
private final String versionName = "toothless dragon";
|
||||
private String btnStyle;
|
||||
|
||||
private final int hashA = -647380320;
|
||||
private int last;
|
||||
private int indexTable;
|
||||
private int indexList;
|
||||
private int next;
|
||||
private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, null);
|
||||
|
||||
private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
|
||||
private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta");
|
||||
private ObservableList<FilmTabelDataType> filterData = FXCollections.observableArrayList();
|
||||
private ObservableList<FilmTabelDataType> filmsList = FXCollections.observableArrayList();
|
||||
private ObservableList<PosterModeElement> posterEmenents = FXCollections.observableArrayList();
|
||||
private static ObservableList<SourceDataType> sourcesList = FXCollections.observableArrayList();
|
||||
private MenuItem like = new MenuItem("like");
|
||||
private MenuItem dislike = new MenuItem("dislike");
|
||||
private ContextMenu menu = new ContextMenu(like, dislike);
|
||||
private LocalDate lastValidCache = LocalDate.now().minusDays(30); // current date - 30 days is the last valid cache date
|
||||
|
||||
public MainWindowController() {
|
||||
|
@ -232,12 +190,10 @@ public class MainWindowController {
|
|||
initUI();
|
||||
initActions();
|
||||
dbController.init();
|
||||
refreshAllFilms();
|
||||
|
||||
// load sources list in gui
|
||||
// load data list in gui
|
||||
addSourceToTable();
|
||||
|
||||
posterModeStartup(); // TODO testing DO NOT USE THIS!!
|
||||
posterModeStartup();
|
||||
}
|
||||
|
||||
// Initialize general UI elements
|
||||
|
@ -271,22 +227,6 @@ public class MainWindowController {
|
|||
* Tabel-Mode
|
||||
*/
|
||||
private void initTabel() {
|
||||
|
||||
// film Table
|
||||
filmsTreeTable.setRoot(filmRoot);
|
||||
filmsTreeTable.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
||||
filmsTreeTable.setShowRoot(false);
|
||||
|
||||
// write content into cell
|
||||
columnStreamUrl.setCellValueFactory(cellData -> cellData.getValue().getValue().streamUrlProperty());
|
||||
columnTitle.setCellValueFactory(cellData -> cellData.getValue().getValue().titleProperty());
|
||||
columnSeason.setCellValueFactory(cellData -> cellData.getValue().getValue().seasonProperty());
|
||||
columnEpisode.setCellValueFactory(cellData -> cellData.getValue().getValue().episodeProperty());
|
||||
columnFavorite.setCellValueFactory(cellData -> cellData.getValue().getValue().imageProperty());
|
||||
|
||||
// context menu for treeTableViewfilm
|
||||
filmsTreeTable.setContextMenu(menu);
|
||||
|
||||
// sourcesTreeTable
|
||||
sourceColumn.setCellValueFactory(cellData -> cellData.getValue().pathProperty());
|
||||
modeColumn.setCellValueFactory(cellData -> cellData.getValue().modeProperty());
|
||||
|
@ -334,113 +274,12 @@ public class MainWindowController {
|
|||
|
||||
fontsizeSlider.valueProperty().addListener(e -> {
|
||||
XMLController.setFontSize(fontsizeSlider.getValue());
|
||||
if (!getCurrentTitle().isEmpty()) {
|
||||
setSelectedFilmInfo(dbController.readCache(getCurrentStreamUrl()));
|
||||
}
|
||||
|
||||
// TODO add functionality for postermode
|
||||
|
||||
xmlController.saveSettings();
|
||||
});
|
||||
|
||||
// Table-Mode actions
|
||||
searchTextField.textProperty().addListener((e, oldValue, newValue) -> {
|
||||
filmRoot.getChildren().clear();
|
||||
filterData.clear();
|
||||
filterData = filmsList.stream()
|
||||
.filter(x -> x.getTitle().toLowerCase().contains(searchTextField.getText().toLowerCase()))
|
||||
.collect(Collectors.toCollection(FXCollections::observableArrayList));
|
||||
|
||||
addFilmsToTable(filterData);
|
||||
|
||||
if (searchTextField.getText().hashCode() == hashA) {
|
||||
XMLController.setColor("000000");
|
||||
colorPicker.setValue(new Color(0, 0, 0, 1));
|
||||
applyColor();
|
||||
}
|
||||
});
|
||||
|
||||
like.setOnAction(e -> {
|
||||
dbController.like(getCurrentStreamUrl());
|
||||
filmsList.set(indexList, dbController.getStream(getCurrentStreamUrl()));
|
||||
refreshTableElement();
|
||||
});
|
||||
|
||||
dislike.setOnAction(e -> {
|
||||
dbController.dislike(getCurrentStreamUrl());
|
||||
filmsList.set(indexList, dbController.getStream(getCurrentStreamUrl()));
|
||||
refreshTableElement();
|
||||
});
|
||||
|
||||
// FIXME fix bug when sort by ASCENDING, wrong order
|
||||
columnFavorite.sortTypeProperty().addListener((e, paramT1, paramT2) -> {
|
||||
filmRoot.getChildren().clear();
|
||||
filterData.clear();
|
||||
|
||||
if (paramT2.equals(SortType.DESCENDING)) {
|
||||
// add favorites at the top
|
||||
for (FilmTabelDataType film : filmsList) {
|
||||
if (film.getFavorite()) {
|
||||
filterData.add(0, film);
|
||||
} else {
|
||||
filterData.add(film);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add favorites at the bottom
|
||||
for (FilmTabelDataType film : filmsList) {
|
||||
if (!film.getFavorite()) {
|
||||
filterData.add(0, film);
|
||||
} else {
|
||||
filterData.add(film);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addFilmsToTable(filterData);
|
||||
});
|
||||
|
||||
// Change-listener for treeTableViewfilm
|
||||
|
||||
filmsTreeTable.getSelectionModel().selectedItemProperty().addListener((e, paramT1, paramT2) -> {
|
||||
if (filmsTreeTable.getSelectionModel().getSelectedItem() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentTableFilm = filmsTreeTable.getSelectionModel().getSelectedItem().getValue(); // set the current film object
|
||||
indexTable = filmsTreeTable.getSelectionModel().getSelectedIndex(); // get selected items table index
|
||||
last = indexTable - 1;
|
||||
next = indexTable + 1;
|
||||
|
||||
for (FilmTabelDataType film : filmsList) {
|
||||
if (film.equals(currentTableFilm)) {
|
||||
indexList = filmsList.indexOf(film); // get selected items list index
|
||||
}
|
||||
}
|
||||
|
||||
if ((dbController.getCacheDate(getCurrentStreamUrl()).isAfter(lastValidCache) || getCurrentStreamUrl().contains("_rootNode"))
|
||||
&& dbController.searchCacheByURL(getCurrentStreamUrl())) {
|
||||
LOGGER.info("loading from cache: " + getCurrentTitle());
|
||||
setSelectedFilmInfo(dbController.readCache(getCurrentStreamUrl()));
|
||||
} else {
|
||||
// this is not perfect!
|
||||
new Thread(() -> {
|
||||
Thread omdbAPIThread = new Thread(new OMDbAPIController(dbController, currentTableFilm, XMLController.getOmdbAPIKey()));
|
||||
omdbAPIThread.setName("OMDbAPI");
|
||||
omdbAPIThread.start();
|
||||
|
||||
synchronized (omdbAPIThread) {
|
||||
try {
|
||||
omdbAPIThread.wait();
|
||||
} catch (InterruptedException e1) {
|
||||
LOGGER.error(e1);
|
||||
}
|
||||
// update the GUI for the selected film
|
||||
Platform.runLater(() -> {
|
||||
setSelectedFilmInfo(dbController.readCache(getCurrentStreamUrl()));
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
|
||||
// Poster-Mode actions
|
||||
}
|
||||
|
||||
|
@ -510,16 +349,6 @@ public class MainWindowController {
|
|||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void returnBtnclicked() {
|
||||
filmsTreeTable.getSelectionModel().select(last);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void forwardBtnclicked() {
|
||||
filmsTreeTable.getSelectionModel().select(next);
|
||||
}
|
||||
|
||||
// general fxml actions
|
||||
@FXML
|
||||
private void aboutBtnAction() {
|
||||
|
@ -585,11 +414,6 @@ public class MainWindowController {
|
|||
xmlController.saveSettings();
|
||||
}
|
||||
|
||||
// refresh the selected child of the root node
|
||||
private void refreshTableElement() {
|
||||
filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList));
|
||||
}
|
||||
|
||||
/**
|
||||
* refresh all films in filmsList and in filmsTable clear the FilmsList and
|
||||
* FilmRoot children, then update the database
|
||||
|
@ -598,65 +422,6 @@ public class MainWindowController {
|
|||
filmsList.clear();
|
||||
dbController.refreshDataBase(); // refreshes the database after a source path was added
|
||||
filmsList = dbController.getStreamsList(); // returns a list of all films stored in the database
|
||||
|
||||
// refresh filmRoot in filmsTreeTable
|
||||
filmRoot.getChildren().clear();
|
||||
addFilmsToTable(filmsList);
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO rework! add data from a ObservableList to the films-table
|
||||
*
|
||||
* @param elementsList a list of elements you want to add
|
||||
*/
|
||||
public void addFilmsToTable(ObservableList<FilmTabelDataType> elementsList) {
|
||||
|
||||
for (FilmTabelDataType element : elementsList) {
|
||||
|
||||
// only if the entry contains a season and a episode it's a valid series
|
||||
if (!element.getSeason().isEmpty() && !element.getEpisode().isEmpty()) {
|
||||
|
||||
// if there is any node check if it's the root node to the episode
|
||||
// else there is no node at all so we must create a new
|
||||
if (filmRoot.getChildren().size() > 0) {
|
||||
for (int i = 0; i < filmRoot.getChildren().size(); i++) {
|
||||
// if a root node exists, add element
|
||||
// else create a new root node and add the element (if rootNode is the last
|
||||
// node) (works since we edit the element!)
|
||||
if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) {
|
||||
TreeItem<FilmTabelDataType> episodeNode = new TreeItem<>(
|
||||
new FilmTabelDataType(element.getStreamUrl(), element.getTitle(),
|
||||
element.getSeason(), element.getEpisode(), element.getFavorite(),
|
||||
element.getImage()));
|
||||
filmRoot.getChildren().get(i).getChildren().add(episodeNode);
|
||||
} else if (filmRoot.getChildren().get(i).nextSibling() == null) {
|
||||
TreeItem<FilmTabelDataType> seriesRootNode = new TreeItem<>(
|
||||
new FilmTabelDataType(element.getTitle() + "_rootNode", element.getTitle(), "", "",
|
||||
element.getFavorite(), element.getImage()));
|
||||
filmRoot.getChildren().add(seriesRootNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add new root node
|
||||
TreeItem<FilmTabelDataType> seriesRootNode = new TreeItem<>(
|
||||
new FilmTabelDataType(element.getTitle() + "_rootNode", element.getTitle(), "", "",
|
||||
element.getFavorite(), element.getImage()));
|
||||
filmRoot.getChildren().add(seriesRootNode);
|
||||
|
||||
// add new element
|
||||
TreeItem<FilmTabelDataType> episodeNode = new TreeItem<>(new FilmTabelDataType(
|
||||
element.getStreamUrl(), element.getTitle(), element.getSeason(), element.getEpisode(),
|
||||
element.getFavorite(), element.getImage()));
|
||||
filmRoot.getChildren().get(0).getChildren().add(episodeNode);
|
||||
}
|
||||
|
||||
} else {
|
||||
// if season and episode are empty, we can assume the object is a film
|
||||
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add a all elements of sourcesList to the sources table on the settings pane
|
||||
|
@ -715,20 +480,12 @@ public class MainWindowController {
|
|||
btnStyle = "-fx-button-type: RAISED; -fx-background-color: #" + XMLController.getColor() + "; -fx-text-fill: WHITE;";
|
||||
menuBtnStyle = "-fx-text-fill: WHITE;";
|
||||
|
||||
playbtn.setGraphic(new ImageView(new Image("icons/ic_play_arrow_white_18dp_1x.png")));
|
||||
returnBtn.setGraphic(new ImageView(new Image("icons/ic_skip_previous_white_18dp_1x.png")));
|
||||
forwardBtn.setGraphic(new ImageView(new Image("icons/ic_skip_next_white_18dp_1x.png")));
|
||||
|
||||
menuHam.getStyleClass().clear();
|
||||
menuHam.getStyleClass().add("jfx-hamburgerW");
|
||||
} else {
|
||||
btnStyle = "-fx-button-type: RAISED; -fx-background-color: #" + XMLController.getColor() + "; -fx-text-fill: BLACK;";
|
||||
menuBtnStyle = "-fx-text-fill: BLACK;";
|
||||
|
||||
playbtn.setGraphic(new ImageView(new Image("icons/ic_play_arrow_black_18dp_1x.png")));
|
||||
returnBtn.setGraphic(new ImageView(new Image("icons/ic_skip_previous_black_18dp_1x.png")));
|
||||
forwardBtn.setGraphic(new ImageView(new Image("icons/ic_skip_next_black_18dp_1x.png")));
|
||||
|
||||
menuHam.getStyleClass().clear();
|
||||
menuHam.getStyleClass().add("jfx-hamburgerB");
|
||||
}
|
||||
|
@ -736,16 +493,11 @@ public class MainWindowController {
|
|||
// boxes and TextFields
|
||||
sideMenuVBox.setStyle("-fx-background-color: #" + XMLController.getColor() + ";");
|
||||
topHBox.setStyle("-fx-background-color: #" + XMLController.getColor() + ";");
|
||||
searchTextField.setFocusColor(Color.valueOf(XMLController.getColor()));
|
||||
|
||||
// normal buttons
|
||||
addDirectoryBtn.setStyle(btnStyle);
|
||||
addStreamSourceBtn.setStyle(btnStyle);
|
||||
updateBtn.setStyle(btnStyle);
|
||||
playbtn.setStyle(btnStyle);
|
||||
openfolderbtn.setStyle(btnStyle);
|
||||
returnBtn.setStyle(btnStyle);
|
||||
forwardBtn.setStyle(btnStyle);
|
||||
|
||||
// menu buttons
|
||||
settingsBtn.setStyle(menuBtnStyle);
|
||||
|
@ -793,8 +545,6 @@ public class MainWindowController {
|
|||
|
||||
aboutBtn.setText(XMLController.getLocalBundle().getString("info"));
|
||||
settingsBtn.setText(XMLController.getLocalBundle().getString("settings"));
|
||||
searchTextField.setPromptText(XMLController.getLocalBundle().getString("tfSearch"));
|
||||
openfolderbtn.setText(XMLController.getLocalBundle().getString("openFolder"));
|
||||
updateBtn.setText(XMLController.getLocalBundle().getString("checkUpdates"));
|
||||
addDirectoryBtn.setText(XMLController.getLocalBundle().getString("addDirectory"));
|
||||
addStreamSourceBtn.setText(XMLController.getLocalBundle().getString("addStreamSource"));
|
||||
|
@ -805,69 +555,6 @@ public class MainWindowController {
|
|||
autoUpdateToggleBtn.setText(XMLController.getLocalBundle().getString("autoUpdate"));
|
||||
autoplayToggleBtn.setText(XMLController.getLocalBundle().getString("autoplay"));
|
||||
branchLbl.setText(XMLController.getLocalBundle().getString("branchLbl"));
|
||||
columnStreamUrl.setText(XMLController.getLocalBundle().getString("columnStreamUrl"));
|
||||
columnTitle.setText(XMLController.getLocalBundle().getString("columnName"));
|
||||
columnFavorite.setText(XMLController.getLocalBundle().getString("columnFavorite"));
|
||||
columnSeason.setText(XMLController.getLocalBundle().getString("columnSeason"));
|
||||
columnEpisode.setText(XMLController.getLocalBundle().getString("columnEpisode"));
|
||||
}
|
||||
|
||||
private void setSelectedFilmInfo(String[] cacheData) {
|
||||
Font font = Font.font("System", FontWeight.BOLD, (int) Math.round(XMLController.getFontSize()));
|
||||
ObservableList<Node> textFlow = getTextFlow().getChildren();
|
||||
|
||||
// TODO this should move! ***
|
||||
Text[] nameText = new Text[20];
|
||||
nameText[0] = new Text(XMLController.getLocalBundle().getString("title") + ": ");
|
||||
nameText[1] = new Text(XMLController.getLocalBundle().getString("year") + ": ");
|
||||
nameText[2] = new Text(XMLController.getLocalBundle().getString("rated") + ": ");
|
||||
nameText[3] = new Text(XMLController.getLocalBundle().getString("released") + ": ");
|
||||
nameText[4] = new Text(XMLController.getLocalBundle().getString("season") + ": ");
|
||||
nameText[5] = new Text(XMLController.getLocalBundle().getString("episode") + ": ");
|
||||
nameText[6] = new Text(XMLController.getLocalBundle().getString("runtime") + ": ");
|
||||
nameText[7] = new Text(XMLController.getLocalBundle().getString("genre") + ": ");
|
||||
nameText[8] = new Text(XMLController.getLocalBundle().getString("directors") + ": ");
|
||||
nameText[9] = new Text(XMLController.getLocalBundle().getString("writers") + ": ");
|
||||
nameText[10] = new Text(XMLController.getLocalBundle().getString("actors") + ": ");
|
||||
nameText[11] = new Text(XMLController.getLocalBundle().getString("plot") + ": ");
|
||||
nameText[12] = new Text(XMLController.getLocalBundle().getString("language") + ": ");
|
||||
nameText[13] = new Text(XMLController.getLocalBundle().getString("country") + ": ");
|
||||
nameText[14] = new Text(XMLController.getLocalBundle().getString("awards") + ": ");
|
||||
nameText[15] = new Text(XMLController.getLocalBundle().getString("metascore") + ": ");
|
||||
nameText[16] = new Text(XMLController.getLocalBundle().getString("imdbRating") + ": ");
|
||||
nameText[17] = new Text(XMLController.getLocalBundle().getString("type") + ": ");
|
||||
nameText[18] = new Text(XMLController.getLocalBundle().getString("boxOffice") + ": ");
|
||||
nameText[19] = new Text(XMLController.getLocalBundle().getString("website") + ": ");
|
||||
// ***
|
||||
|
||||
// set the correct font for the nameText
|
||||
for (Text text : nameText) {
|
||||
text.setFont(font);
|
||||
}
|
||||
|
||||
// clear the textFlow and add the new text
|
||||
textFlow.clear();
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
// if the cacheData exists and they are not empty add the text
|
||||
if(cacheData[i] != null && cacheData[i].length() > 0) {
|
||||
textFlow.addAll(nameText[i], new Text(cacheData[i] + "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
getTextFlow().setStyle("-fx-font-size : " + ((int) Math.round(XMLController.getFontSize()) + 1) + "px;");
|
||||
|
||||
// add the image
|
||||
try {
|
||||
if (new File(cacheData[20]).isFile()) {
|
||||
posterImageView.setImage(new Image(new File(cacheData[20]).toURI().toString()));
|
||||
} else {
|
||||
posterImageView.setImage(new Image(cacheData[20]));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
posterImageView.setImage(new Image("icons/Homeflix_Poster.png"));
|
||||
LOGGER.error("No Poster found, useing default.");
|
||||
}
|
||||
}
|
||||
|
||||
// if AutoUpdate, then check for updates
|
||||
|
@ -905,7 +592,8 @@ public class MainWindowController {
|
|||
|
||||
private void posterModeStartup() {
|
||||
checkAllPosters();
|
||||
addGUIElements();
|
||||
addAllPosters();
|
||||
checkCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -918,7 +606,7 @@ public class MainWindowController {
|
|||
for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) {
|
||||
System.out.println(entry.getStreamUrl() + " is NOT cached!");
|
||||
|
||||
Runnable OMDbAPIWorker = new OMDbAPIController(dbController, entry, XMLController.getOmdbAPIKey());
|
||||
Runnable OMDbAPIWorker = new OMDbAPIController(entry, XMLController.getOmdbAPIKey());
|
||||
executor.execute(OMDbAPIWorker);
|
||||
}
|
||||
executor.shutdown();
|
||||
|
@ -940,7 +628,7 @@ public class MainWindowController {
|
|||
/**
|
||||
* add all cached films/series to the PosterMode GUI
|
||||
*/
|
||||
private void addGUIElements() {
|
||||
private void addAllPosters() {
|
||||
// refresh the posterModeElements list
|
||||
posterEmenents.clear();
|
||||
posterEmenents = dbController.getPosterElementsList(); // returns a list of all PosterElements stored in the database
|
||||
|
@ -949,19 +637,16 @@ public class MainWindowController {
|
|||
for (PosterModeElement element : posterEmenents) {
|
||||
element.getButton().addEventHandler(MouseEvent.MOUSE_CLICKED, (event) -> {
|
||||
enableBlur(); // blur the FlowPane
|
||||
System.out.println("selected: " + element.getStreamURL());
|
||||
|
||||
// if the selected element is a file it's a film, else a series
|
||||
if (new File(element.getStreamURL()).isFile()) {
|
||||
if (new File(element.getStreamURL()).isFile() || element.getStreamURL().contains("http")) {
|
||||
filmDetailViewController.setFilm(element.getStreamURL());
|
||||
filmDetailViewController.showPane();
|
||||
} else {
|
||||
// filmDetailViewController.setFilm(element.getStreamURL());
|
||||
// filmDetailViewController.showPane();
|
||||
seriesDetailViewController.setSeries(element.getStreamURL());
|
||||
seriesDetailViewController.showPane();
|
||||
}
|
||||
|
||||
System.out.println("selected: " + element.getStreamURL());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -971,6 +656,25 @@ public class MainWindowController {
|
|||
System.out.println("added gui elements");
|
||||
}
|
||||
|
||||
// TODO can this be done in dbController?
|
||||
/**
|
||||
* check if the cache is to old, if so update asynchron
|
||||
*/
|
||||
private void checkCache() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(5);
|
||||
|
||||
// TODO if filmlist is not used anymore, it cann be removed
|
||||
for(FilmTabelDataType entry : filmsList) {
|
||||
if (dbController.getCacheDate(entry.getStreamUrl()).isBefore(lastValidCache)) {
|
||||
System.out.println(entry.getTitle() + " chached on: " + dbController.getCacheDate(entry.getStreamUrl()));
|
||||
Runnable OMDbAPIWorker = new OMDbAPIController(entry, XMLController.getOmdbAPIKey());
|
||||
executor.execute(OMDbAPIWorker);
|
||||
}
|
||||
}
|
||||
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
private void enableBlur() {
|
||||
BoxBlur boxBlur = new BoxBlur();
|
||||
boxBlur.setWidth(9);
|
||||
|
@ -997,22 +701,10 @@ public class MainWindowController {
|
|||
return currentTableFilm.getStreamUrl();
|
||||
}
|
||||
|
||||
public int getIndexTable() {
|
||||
return indexTable;
|
||||
}
|
||||
|
||||
public int getIndexList() {
|
||||
return indexList;
|
||||
}
|
||||
|
||||
public static ObservableList<SourceDataType> getSourcesList() {
|
||||
return sourcesList;
|
||||
}
|
||||
|
||||
public TextFlow getTextFlow() {
|
||||
return textFlow;
|
||||
}
|
||||
|
||||
public JFXButton getUpdateBtn() {
|
||||
return updateBtn;
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@ public class OMDbAPIController implements Runnable {
|
|||
* @param currentTableFilm the current film object
|
||||
* @param omdbAPIKey the omdbAPI key
|
||||
*/
|
||||
public OMDbAPIController(DBController dbController, FilmTabelDataType currentTableFilm, String omdbAPIKey) {
|
||||
this.dbController = dbController;
|
||||
public OMDbAPIController(FilmTabelDataType currentTableFilm, String omdbAPIKey) {
|
||||
this.currentTableFilm = currentTableFilm;
|
||||
this.omdbAPIKey = omdbAPIKey;
|
||||
dbController = DBController.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -66,6 +66,10 @@ public class PlayerController {
|
|||
@FXML private JFXButton fullscreenBtn;
|
||||
@FXML private JFXButton nextEpBtn;
|
||||
|
||||
@FXML private ImageView stopIcon;
|
||||
@FXML private ImageView playIcon;
|
||||
@FXML private ImageView fullscreenIcon;
|
||||
|
||||
private Player player;
|
||||
private Media media;
|
||||
private MediaPlayer mediaPlayer;
|
||||
|
@ -82,11 +86,10 @@ public class PlayerController {
|
|||
private boolean showControls = true;
|
||||
private boolean autoplay;
|
||||
|
||||
private ImageView stop_black = new ImageView(new Image("icons/ic_stop_black_24dp_1x.png"));
|
||||
private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_24dp_1x.png"));
|
||||
private ImageView pause_black = new ImageView(new Image("icons/ic_pause_black_24dp_1x.png"));
|
||||
private ImageView fullscreen_black = new ImageView(new Image("icons/ic_fullscreen_black_24dp_1x.png"));
|
||||
private ImageView fullscreen_exit_black = new ImageView(new Image("icons/ic_fullscreen_exit_black_24dp_1x.png"));
|
||||
private Image playArrow = new Image("icons/baseline_play_arrow_black_48dp.png");
|
||||
private Image pause = new Image("icons/baseline_pause_black_48dp.png");
|
||||
private Image fullscreen = new Image("icons/baseline_fullscreen_black_48dp.png");
|
||||
private Image fullscreenExit = new Image("icons/baseline_fullscreen_exit_black_48dp.png");
|
||||
|
||||
/**
|
||||
* create a new PlayerWindow object
|
||||
|
@ -130,9 +133,8 @@ public class PlayerController {
|
|||
initMediaPlayer();
|
||||
|
||||
// set the control elements to the correct value
|
||||
stopBtn.setGraphic(stop_black);
|
||||
playBtn.setGraphic(pause_black);
|
||||
fullscreenBtn.setGraphic(fullscreen_exit_black);
|
||||
playIcon.setImage(pause);
|
||||
fullscreenIcon.setImage(fullscreenExit);
|
||||
timeSlider.setValue(0);
|
||||
}
|
||||
|
||||
|
@ -176,7 +178,7 @@ public class PlayerController {
|
|||
// if we are 120ms to the end stop the media
|
||||
mediaPlayer.stop();
|
||||
DBController.getInstance().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
|
||||
playBtn.setGraphic(play_arrow_black);
|
||||
playIcon.setImage(playArrow);
|
||||
} else {
|
||||
if (nextEpBtn.isVisible())
|
||||
nextEpBtn.setVisible(false);
|
||||
|
@ -262,10 +264,10 @@ public class PlayerController {
|
|||
void fullscreenBtnAction(ActionEvent event) {
|
||||
if (player.getStage().isFullScreen()) {
|
||||
player.getStage().setFullScreen(false);
|
||||
fullscreenBtn.setGraphic(fullscreen_black);
|
||||
fullscreenIcon.setImage(fullscreen);
|
||||
} else {
|
||||
player.getStage().setFullScreen(true);
|
||||
fullscreenBtn.setGraphic(fullscreen_exit_black);
|
||||
fullscreenIcon.setImage(fullscreenExit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,10 +275,10 @@ public class PlayerController {
|
|||
void playBtnAction(ActionEvent event) {
|
||||
if (mediaPlayer.getStatus().equals(Status.PLAYING)) {
|
||||
mediaPlayer.pause();
|
||||
playBtn.setGraphic(play_arrow_black);
|
||||
playIcon.setImage(playArrow);
|
||||
} else {
|
||||
mediaPlayer.play();
|
||||
playBtn.setGraphic(pause_black);
|
||||
playIcon.setImage(pause);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,13 @@
|
|||
-fx-background-insets: 0.0;
|
||||
}
|
||||
|
||||
.scroll-bar:vertical > .thumb, .scroll-bar:horizontal > .thumb {
|
||||
.scroll-bar:vertical > .thumb {
|
||||
-fx-background-color: #BCBCBC;
|
||||
-fx-background-insets: 0.0;
|
||||
-fx-background-radius: 15.0;
|
||||
}
|
||||
|
||||
.scroll-bar:horizontal > .thumb {
|
||||
-fx-background-color: #FFFFFF;
|
||||
-fx-background-insets: 0.0;
|
||||
-fx-background-radius: 15.0;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<?import com.jfoenix.controls.JFXColorPicker?>
|
||||
<?import com.jfoenix.controls.JFXHamburger?>
|
||||
<?import com.jfoenix.controls.JFXSlider?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import com.jfoenix.controls.JFXToggleButton?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
|
@ -13,58 +12,14 @@
|
|||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.TreeTableColumn?>
|
||||
<?import javafx.scene.control.TreeTableView?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.FlowPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
|
||||
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.MainWindowController">
|
||||
<children>
|
||||
<AnchorPane fx:id="tableModeAnchorPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||
<children>
|
||||
<JFXTextField fx:id="searchTextField" maxWidth="-Infinity" minWidth="420.0" prefHeight="31.0" promptText="search ..." AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="12.0">
|
||||
<font>
|
||||
<Font name="Arial" size="12.0" />
|
||||
</font>
|
||||
</JFXTextField>
|
||||
<TreeTableView fx:id="filmsTreeTable" prefHeight="500.0" prefWidth="420.0" AnchorPane.bottomAnchor="12.0" AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="56.0">
|
||||
<columns>
|
||||
<TreeTableColumn fx:id="columnStreamUrl" editable="false" prefWidth="75.0" resizable="false" text="Stream URL" visible="false" />
|
||||
<TreeTableColumn fx:id="columnTitle" maxWidth="276.0" minWidth="276.0" prefWidth="276.0" resizable="false" text="Title" />
|
||||
<TreeTableColumn fx:id="columnFavorite" maxWidth="100.0" minWidth="100.0" prefWidth="100.0" resizable="false" style="-fx-alignment: CENTER;" text="Favorite" />
|
||||
<TreeTableColumn fx:id="columnSeason" maxWidth="80.0" minWidth="80.0" resizable="false" text="Season" />
|
||||
<TreeTableColumn fx:id="columnEpisode" maxWidth="80.0" minWidth="80.0" resizable="false" text="Episode" />
|
||||
</columns></TreeTableView>
|
||||
<ScrollPane fx:id="textScrollPane" fitToWidth="true" prefHeight="544.0" prefWidth="320.0" AnchorPane.bottomAnchor="12.0" AnchorPane.rightAnchor="222.0" AnchorPane.topAnchor="12.0">
|
||||
<content>
|
||||
<TextFlow fx:id="textFlow" accessibleRole="TEXT_AREA" maxHeight="544.0" maxWidth="320.0" visible="true" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<ImageView fx:id="posterImageView" fitHeight="297.0" fitWidth="198.0" pickOnBounds="true" preserveRatio="true" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="12.0">
|
||||
<image>
|
||||
<Image url="@../icons/Homeflix_Poster.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
<JFXButton fx:id="playbtn" contentDisplay="CENTER" onAction="#playbtnclicked" prefHeight="25.0" prefWidth="198.0" AnchorPane.bottomAnchor="212.0" AnchorPane.rightAnchor="12.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
</JFXButton>
|
||||
<JFXButton fx:id="openfolderbtn" onAction="#openfolderbtnclicked" prefHeight="25.0" prefWidth="198.0" text="open Folder" AnchorPane.bottomAnchor="171.0" AnchorPane.rightAnchor="12.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
</JFXButton>
|
||||
<JFXButton fx:id="returnBtn" contentDisplay="CENTER" onAction="#returnBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="120.0" />
|
||||
<JFXButton fx:id="forwardBtn" contentDisplay="CENTER" onAction="#forwardBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="12.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<ScrollPane fx:id="posterModeScrollPane" fitToWidth="true" layoutX="10.0" layoutY="48.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||
<content>
|
||||
<FlowPane fx:id="posterModeFlowPane" hgap="3.0" vgap="7.0">
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXSlider?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.media.MediaView?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane prefHeight="720.0" prefWidth="1280.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<AnchorPane prefHeight="720.0" prefWidth="1280.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<HBox alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
|
@ -25,15 +27,39 @@
|
|||
</JFXSlider>
|
||||
<HBox fx:id="controlsHBox" alignment="CENTER" spacing="10.0">
|
||||
<children>
|
||||
<JFXButton fx:id="stopBtn" buttonType="RAISED" onAction="#stopBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||
<JFXButton fx:id="playBtn" buttonType="RAISED" onAction="#playBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||
<JFXButton fx:id="fullscreenBtn" buttonType="RAISED" onAction="#fullscreenBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||
<JFXButton fx:id="stopBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#stopBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="stopIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_stop_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
<JFXButton fx:id="playBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#playBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="playIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_play_arrow_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
<JFXButton fx:id="fullscreenBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#fullscreenBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="fullscreenIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_fullscreen_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
<JFXButton fx:id="nextEpBtn" onAction="#nextEpBtnAction" style="-fx-background-color: ee3523;" text="next episode in 10 seconds" textFill="WHITE" visible="false" AnchorPane.bottomAnchor="80.0" AnchorPane.rightAnchor="20.0">
|
||||
<font>
|
||||
|
|
|
@ -122,12 +122,16 @@
|
|||
<content>
|
||||
<HBox fx:id="hBoxEpisodes" maxHeight="-Infinity" minHeight="-Infinity" prefHeight="117.0" spacing="10.0">
|
||||
<padding>
|
||||
<Insets left="10.0" right="10.0" top="5.0" />
|
||||
<Insets left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<ChoiceBox fx:id="cbSeason" layoutX="22.0" layoutY="523.0" prefHeight="25.0" prefWidth="168.0" AnchorPane.leftAnchor="22.0" AnchorPane.topAnchor="515.0" />
|
||||
<HBox style="-fx-background-color: #ffffff;" AnchorPane.leftAnchor="22.0" AnchorPane.topAnchor="515.0">
|
||||
<children>
|
||||
<ChoiceBox fx:id="cbSeason" prefHeight="25.0" prefWidth="168.0" />
|
||||
</children>
|
||||
</HBox>
|
||||
<JFXButton fx:id="btnHide" contentDisplay="GRAPHIC_ONLY" layoutX="532.0" layoutY="520.0" maxHeight="-Infinity" minWidth="-Infinity" onAction="#btnHideAction" prefHeight="32.0" style="-fx-background-color: transparent;" text="Hide" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="530.0" AnchorPane.rightAnchor="530.0">
|
||||
<graphic>
|
||||
<ImageView pickOnBounds="true" preserveRatio="true">
|
||||
|
|
After Width: | Height: | Size: 109 B |
After Width: | Height: | Size: 111 B |
After Width: | Height: | Size: 107 B |
After Width: | Height: | Size: 107 B |
Before Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 81 B |
Before Width: | Height: | Size: 131 B |
Before Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 135 B |
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 128 B |
Before Width: | Height: | Size: 134 B |
Before Width: | Height: | Size: 131 B |
Before Width: | Height: | Size: 138 B |
Before Width: | Height: | Size: 82 B |