[gnome-sound-recorder] recording list: split into a ListModel & UI
- From: Bilal Elmoussaoui <bilelmoussaoui src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-sound-recorder] recording list: split into a ListModel & UI
- Date: Wed, 8 Apr 2020 22:04:46 +0000 (UTC)
commit 9dd7da5eed1432d8999df1f3cfa02d60951ee449
Author: Kavan Mevada <kavanmevada gmail com>
Date: Wed Apr 8 22:04:40 2020 +0000
recording list: split into a ListModel & UI
data/ui/infodialog.ui | 6 +-
data/ui/window.ui | 120 +++++++-
src/info.js | 21 +-
src/listview.js | 338 -----------------------
src/mainWindow.js | 191 ++++---------
src/org.gnome.SoundRecorder.src.gresource.xml.in | 3 +-
src/record.js | 3 +-
src/recording.js | 82 ++++++
src/recordingList.js | 78 ++++++
src/row.js | 22 +-
src/utils.js | 44 ++-
src/waveform.js | 5 +-
12 files changed, 374 insertions(+), 539 deletions(-)
---
diff --git a/data/ui/infodialog.ui b/data/ui/infodialog.ui
index e94f1c4..2e38829 100644
--- a/data/ui/infodialog.ui
+++ b/data/ui/infodialog.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
- <requires lib="gtk+" version="3.10"/>
+ <requires lib="gtk+" version="3.12"/>
<template class="Gjs_InfoDialog" parent="GtkWindow">
<property name="can_focus">False</property>
<property name="modal">True</property>
@@ -72,7 +72,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel">
+ <object class="GtkLabel" id="dateCreatedLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
@@ -136,7 +136,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="dateCreatedLabel">
+ <object class="GtkLabel" id="dateCreatedValueLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
diff --git a/data/ui/window.ui b/data/ui/window.ui
index 098d6b7..ffda6ff 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -15,16 +15,119 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
- <object class="GtkGrid" id="mainView">
+ <object class="GtkGrid">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkListBox" id="listBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="recordGrid">
+ <property name="can_focus">False</property>
+ <property name="margin_start">18</property>
+ <property name="margin_end">18</property>
+ <property name="margin_top">18</property>
+ <property name="margin_bottom">18</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkButton" id="recordStopButton">
+ <property name="label" translatable="yes">Done</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="margin_left">6</property>
+ <property name="margin_start">18</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">4</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box-record">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="margin_end">18</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">8</property>
+ <property name="label" translatable="yes">Recording</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="recordTimeLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
</object>
<packing>
- <property name="position">0</property>
+ <property name="name">mainView</property>
</packing>
</child>
<child>
- <object class="GtkGrid" id="emptyView">
+ <object class="GtkGrid">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
@@ -38,6 +141,7 @@
<property name="vexpand">True</property>
<child>
<object class="GtkImage">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
@@ -54,6 +158,7 @@
</child>
<child>
<object class="GtkLabel">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Use the <b>Record</b> button to
make sound recordings</property>
<property name="use_markup">True</property>
@@ -69,6 +174,7 @@
</child>
<child>
<object class="GtkLabel">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Add Recordings</property>
<style>
@@ -88,18 +194,20 @@
</child>
</object>
<packing>
+ <property name="name">emptyView</property>
<property name="position">1</property>
</packing>
</child>
- </object>
- </child>
+ </object>
+ </child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerBar">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Sound Recorder</property>
<property name="show_close_button">True</property>
<child>
- <object class="GtkButton" id="recordButton">
+ <object class="GtkButton" id="recordStartButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
diff --git a/src/info.js b/src/info.js
index 025a0ad..90dc799 100644
--- a/src/info.js
+++ b/src/info.js
@@ -23,31 +23,32 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const GObject = imports.gi.GObject;
+const Utils = imports.utils;
var InfoDialog = GObject.registerClass({ // eslint-disable-line no-unused-vars
Template: 'resource:///org/gnome/SoundRecorder/ui/infodialog.ui',
- InternalChildren: ['cancelBtn', 'doneBtn', 'fileNameEntry', 'sourceLabel', 'dateModifiedLabel',
'dateModifiedValueLabel', 'dateCreatedLabel', 'mediaTypeLabel'],
+ InternalChildren: ['cancelBtn', 'doneBtn', 'fileNameEntry', 'sourceLabel', 'dateModifiedValueLabel',
'dateCreatedLabel', 'dateCreatedValueLabel', 'mediaTypeLabel'],
}, class InfoDialog extends Gtk.Window {
- _init(file) {
- this._file = Gio.File.new_for_uri(file.uri);
+ _init(recording) {
+ this._file = Gio.File.new_for_uri(recording.uri);
super._init({ transient_for: Gio.Application.get_default().get_active_window() });
- this._fileNameEntry.text = file.fileName;
+ this._fileNameEntry.text = recording.name;
// Source value
this._sourceLabel.label = this._file.get_parent().get_path();
- if (file.dateModified !== null) {
- this._dateModifiedValueLabel.label = file.dateModified;
+ if (recording.timeCreated > 0) {
+ this._dateCreatedValueLabel.label = Utils.Time.getDisplayTime(recording.timeCreated);
} else {
- this._dateModifiedValueLabel.destroy();
- this._dateModifiedLabel.destroy();
+ this._dateCreatedValueLabel.destroy();
+ this._dateCreatedLabel.destroy();
}
- this._dateCreatedLabel.label = file.dateCreated;
- this._mediaTypeLabel.label = file.mediaType || _('Unknown');
+ this._dateModifiedValueLabel.label = Utils.Time.getDisplayTime(recording.timeModified);
+ this._mediaTypeLabel.label = recording.mimeType || _('Unknown');
this._cancelBtn.connect('clicked', () => {
this.destroy();
diff --git a/src/mainWindow.js b/src/mainWindow.js
index ba57453..5929964 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -25,10 +25,10 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
-const Settings = imports.preferences.settings;
const AudioProfile = imports.audioProfile;
const Utils = imports.utils;
-const Listview = imports.listview;
+const RecordingList = imports.recordingList.RecordingList;
+const Recording = imports.recording.Recording;
const Row = imports.row.Row;
const RowState = imports.row.RowState;
const Player = imports.player.Player;
@@ -38,7 +38,6 @@ const Waveform = imports.waveform;
let activeProfile = null;
var audioProfile = null;
var displayTime = null;
-var list = null;
var player = null;
var recordPipeline = null;
var view = null;
@@ -51,23 +50,43 @@ var ActiveArea = {
var MainWindow = GObject.registerClass({
Template: 'resource:///org/gnome/SoundRecorder/ui/window.ui',
- InternalChildren: ['recordButton', 'appMenuButton', 'mainStack', 'mainView', 'emptyView'],
+ InternalChildren: ['recordStartButton', 'recordStopButton', 'recordTimeLabel', 'appMenuButton',
'mainStack', 'recordGrid', 'listBox'],
}, class MainWindow extends Gtk.ApplicationWindow {
_init(params) {
- audioProfile = new AudioProfile.AudioProfile();
- displayTime = new Utils.DisplayTime();
- view = this;
- this._addListviewPage();
- player = new Player();
-
super._init(Object.assign({
icon_name: pkg.name,
}, params));
- this._recordButton.connect('clicked', () => this._onRecord());
+ audioProfile = new AudioProfile.AudioProfile();
+ this._record = new Record.Record(audioProfile);
+ player = new Player();
+ view = this;
+
+ this._recordingList = new RecordingList();
+ this._refreshView();
+ this._recordingList.connect('items-changed', this._refreshView.bind(this));
+
+ this._listBox.bind_model(this._recordingList, recording => {
+ let row = new Row(recording);
+ row.connect('play', currentRow => {
+ this._listBox.get_children().forEach(_row => {
+ if (_row !== currentRow)
+ _row.setState(RowState.PAUSED);
+ });
+ player.startPlaying(recording.uri);
+ });
+
+ row.connect('pause', () => player.pausePlaying());
+ row.connect('deleted', () => this._recordingList.remove(row.get_index()));
+
+ return row;
+ });
+
+ this._recordStartButton.connect('clicked', () => this._onRecordStart());
+ this._recordStopButton.connect('clicked', () => this._onRecordStop());
this._addAppMenu();
- this.show_all();
+ this.show();
}
_addAppMenu() {
@@ -77,150 +96,42 @@ var MainWindow = GObject.registerClass({
this._appMenuButton.set_menu_model(menu);
}
- _onRecord() {
- if (view.listBox)
- view.listBox.set_selection_mode(Gtk.SelectionMode.NONE);
- else
- this._mainStack.set_visible_child(this._mainView);
-
- this._recordButton.set_sensitive(false);
- view.recordGrid.show_all();
+ _onRecordStart() {
+ player.stopPlaying();
+ this._mainStack.set_visible_child_name('mainView');
+ this._recordGrid.show();
if (activeProfile === null)
activeProfile = 0;
audioProfile.profile(activeProfile);
- view._record.startRecording(activeProfile);
- wave = new Waveform.WaveForm(view.recordGrid, null);
- }
+ this._record.startRecording(activeProfile);
- _addListviewPage() {
- list = new Listview.Listview();
- list.setListTypeNew();
- list.enumerateDirectory();
- this._record = new Record.Record(audioProfile);
+ wave = new Waveform.WaveForm(this._recordGrid, null);
}
- onRecordStopClicked() {
+ _onRecordStop() {
Record.pipeState = Record.PipelineStates.STOPPED;
this._record.stopRecording();
- this.recordGrid.hide();
- this._recordButton.set_sensitive(true);
- wave = null;
- }
-
- _updatePositionCallback() {
- let position = player.queryPosition();
-
- if (position >= 0)
- this.progressScale.set_value(position);
-
- return true;
- }
-
- listBoxAdd() {
- activeProfile = Settings.mediaCodec;
-
- this.recordGrid = new Gtk.Grid({ name: 'recordGrid',
- orientation: Gtk.Orientation.HORIZONTAL });
- this._mainView.add(this.recordGrid);
-
- this.widgetRecord = new Gtk.Toolbar({ show_arrow: false,
- halign: Gtk.Align.END,
- valign: Gtk.Align.FILL,
- icon_size: Gtk.IconSize.BUTTON,
- opacity: 1 });
- this.recordGrid.attach(this.widgetRecord, 0, 0, 2, 2);
-
- this._boxRecord = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
- this._groupRecord = new Gtk.ToolItem({ child: this._boxRecord });
- this.widgetRecord.insert(this._groupRecord, -1);
-
- this.recordTextLabel = new Gtk.Label({ margin_bottom: 4,
- margin_end: 6,
- margin_start: 6,
- margin_top: 6 });
- this.recordTextLabel.label = _('Recording…');
- this._boxRecord.pack_start(this.recordTextLabel, false, true, 0);
-
- this.recordTimeLabel = new Gtk.Label({ margin_bottom: 4,
- margin_end: 6,
- margin_start: 6,
- margin_top: 6 });
-
- this._boxRecord.pack_start(this.recordTimeLabel, false, true, 0);
-
- this.toolbarStart = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, expand: false });
- this.toolbarStart.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED);
-
- // finish button (stop recording)
- let stopRecord = new Gtk.Button({ label: _('Done'),
- halign: Gtk.Align.FILL,
- valign: Gtk.Align.CENTER,
- hexpand: true,
- margin_bottom: 4,
- margin_end: 6,
- margin_start: 6,
- margin_top: 6 });
- stopRecord.get_style_context().add_class('text-button');
- stopRecord.connect('clicked', () => this.onRecordStopClicked());
- this.toolbarStart.pack_start(stopRecord, true, true, 0);
- this.recordGrid.attach(this.toolbarStart, 5, 1, 2, 2);
- }
+ this._recordGrid.hide();
- scrolledWinAdd() {
- this._scrolledWin = new Gtk.ScrolledWindow({ vexpand: true });
- this._scrolledWin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
- this.scrollbar = this._scrolledWin.get_vadjustment();
-
- this._mainView.add(this._scrolledWin);
- this._scrolledWin.show();
-
- this.listBox = null;
-
- if (list.getItemCount() === 0) {
- this._scrolledWin.get_style_context().add_class('emptyGrid');
- this._mainStack.set_visible_child(this._emptyView);
- } else {
- this.listBox = new Gtk.ListBox({ vexpand: true });
- this._scrolledWin.add(this.listBox);
- this.listBox.set_selection_mode(Gtk.SelectionMode.SINGLE);
- this.listBox.set_header_func(null);
- this.listBox.set_activate_on_single_click(true);
- this.listBox.show();
-
- this._files = [];
- this._files = list.getFilesInfoForList();
-
- this._files.forEach(file => {
- let row = new Row(file);
- row.connect('play', (playingRow, fileUri) => {
- this.listBox.get_children().forEach(_row => {
- if (_row !== playingRow)
- _row.setState(RowState.PAUSED);
- });
- player.startPlaying(fileUri);
- });
- row.connect('pause', () => player.pausePlaying());
- this.listBox.add(row);
- });
- }
- list.monitorListview();
- }
+ let fileUri = this._record.initialFileName;
+ let recordedFile = Gio.file_new_for_path(fileUri);
+ let recording = new Recording(recordedFile);
+ this._recordingList.insert(0, recording);
- listBoxRefresh() {
- list.setListTypeRefresh();
- list.enumerateDirectory();
+ wave = null;
}
- scrolledWinDelete() {
- this._scrolledWin.destroy();
- this.scrolledWinAdd();
+ _refreshView() {
+ if (this._recordingList.get_n_items() === 0)
+ this._mainStack.set_visible_child_name('emptyView');
+ else
+ this._mainStack.set_visible_child_name('mainView');
}
setRecordTimeLabel(time) {
- this.timeLabelString = Utils.StringUtils.formatTime(time);
- this.recordTimeLabel.label = this.timeLabelString;
- this.recordTimeLabel.get_style_context().add_class('dim-label');
+ let timeLabelString = Utils.Time.formatTime(time);
+ this._recordTimeLabel.label = timeLabelString;
}
});
diff --git a/src/org.gnome.SoundRecorder.src.gresource.xml.in
b/src/org.gnome.SoundRecorder.src.gresource.xml.in
index 32ce3fe..988ddb7 100644
--- a/src/org.gnome.SoundRecorder.src.gresource.xml.in
+++ b/src/org.gnome.SoundRecorder.src.gresource.xml.in
@@ -5,7 +5,8 @@
<file>audioProfile.js</file>
<file>utils.js</file>
<file>info.js</file>
- <file>listview.js</file>
+ <file>recordingList.js</file>
+ <file>recording.js</file>
<file>row.js</file>
<file>main.js</file>
<file>mainWindow.js</file>
diff --git a/src/record.js b/src/record.js
index cc547c5..8903b95 100644
--- a/src/record.js
+++ b/src/record.js
@@ -54,7 +54,6 @@ var Record = class Record {
_recordPipeline() {
errorDialogState = ErrState.OFF;
this.baseTime = 0;
- this._view = MainWindow.view;
this._buildFileName = new BuildFileName();
this.initialFileName = this._buildFileName.buildInitialFilename();
let localDateTime = this._buildFileName.getOrigin();
@@ -148,7 +147,7 @@ var Record = class Record {
let time = this.pipeline.query_position(Gst.Format.TIME)[1] / Gst.SECOND;
if (time >= 0)
- this._view.setRecordTimeLabel(time, 0);
+ MainWindow.view.setRecordTimeLabel(time, 0);
return true;
diff --git a/src/recording.js b/src/recording.js
new file mode 100644
index 0000000..988da51
--- /dev/null
+++ b/src/recording.js
@@ -0,0 +1,82 @@
+const GLib = imports.gi.GLib;
+const Gst = imports.gi.Gst;
+const GObject = imports.gi.GObject;
+const GstPbutils = imports.gi.GstPbutils;
+
+
+var Recording = new GObject.registerClass({ // eslint-disable-line no-unused-vars
+ Properties: {
+ 'duration': GObject.ParamSpec.int(
+ 'duration',
+ 'Recording Duration', 'Recording duration in seconds',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
+ 0, GLib.MAXINT, 0),
+
+ 'mime-type': GObject.ParamSpec.string(
+ 'mime-type',
+ 'Recording Audio Codec', 'Recording audio codec type',
+ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, ''),
+ },
+}, class Recording extends GObject.Object {
+ _init(file) {
+ super._init({});
+ this._file = file;
+
+ this._name = file.get_basename();
+
+ let info = file.query_info('time::created,time::modified', 0, null);
+
+ let timeModified = info.get_attribute_uint64('time::modified');
+ let timeCreated = info.get_attribute_uint64('time::created');
+ this._timeModified = GLib.DateTime.new_from_unix_local(timeModified);
+ this._timeCreated = GLib.DateTime.new_from_unix_local(timeCreated);
+
+ var discoverer = new GstPbutils.Discoverer();
+ discoverer.start();
+ discoverer.connect('discovered', (_discoverer, audioInfo) => {
+ this._duration = audioInfo.get_duration() / Gst.SECOND;
+ this.notify('duration');
+
+ let stream = audioInfo.get_audio_streams()[0];
+ if (stream) {
+ this._mimeType = stream.get_caps().to_string().split(', ')[0];
+ this.notify('mime-type');
+ }
+ });
+
+ discoverer.discover_uri_async(this.uri);
+ }
+
+ get name() {
+ return this._name;
+ }
+
+ get timeModified() {
+ return this._timeModified;
+ }
+
+ get timeCreated() {
+ return this._timeCreated;
+ }
+
+ get duration() {
+ return this._duration;
+ }
+
+ get mimeType() {
+ return this._mimeType;
+ }
+
+ get file() {
+ return this._file;
+ }
+
+ get uri() {
+ return this._file.get_uri();
+ }
+
+ delete() {
+ return this._file.trash_async(GLib.PRIORITY_DEFAULT, null, null);
+ }
+
+});
diff --git a/src/recordingList.js b/src/recordingList.js
new file mode 100644
index 0000000..2cfde79
--- /dev/null
+++ b/src/recordingList.js
@@ -0,0 +1,78 @@
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+
+const Recording = imports.recording.Recording;
+
+
+var RecordingList = new GObject.registerClass(class RecordingList extends Gio.ListStore { //
eslint-disable-line no-unused-vars
+ _init() {
+ super._init({ });
+ this._saveDir = Gio.Application.get_default().saveDir;
+
+ // Monitor Direcotry actions
+ let dirMonitor = this._saveDir.monitor_directory(Gio.FileMonitorFlags.WATCH_MOVES, null);
+ dirMonitor.connect('changed', (_dirMonitor, file1, file2, eventType) => {
+ // Monitor if file action done on _saveDir
+ let index = this.getIndex(file1);
+
+ switch (eventType) {
+ case Gio.FileMonitorEvent.DELETED:
+ if (Gio.Application.get_default().saveDir.equal(file1)) {
+ Gio.Application.get_default().ensureDirectory();
+ this._saveDir = Gio.Application.get_default().saveDir;
+ }
+ break;
+ case Gio.FileMonitorEvent.MOVED_OUT:
+ if (index >= 0)
+ this.remove(index);
+ break;
+ case Gio.FileMonitorEvent.MOVED_IN:
+ if (index === -1)
+ this.insert(0, new Recording(file1));
+ break;
+ }
+
+ });
+ this._watchDir();
+ }
+
+ _watchDir() {
+ this._saveDir.enumerate_children_async('standard::name',
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ GLib.PRIORITY_LOW,
+ null,
+ (obj, res) => this._enumerateDirectory(obj, res));
+ }
+
+
+ _enumerateDirectory(obj, res) {
+ this._enumerator = obj.enumerate_children_finish(res);
+
+ if (this._enumerator === null) {
+ log('The contents of the Recordings directory were not indexed.');
+ } else {
+ this._enumerator.next_files_async(20, GLib.PRIORITY_DEFAULT, null, (_obj, _res) => {
+ let fileInfos = _obj.next_files_finish(_res);
+ if (fileInfos.length > 0) {
+ fileInfos.forEach(info => {
+ let path = GLib.build_filenamev([this._saveDir.get_path(), info.get_name()]);
+ let file = Gio.file_new_for_path(path);
+ let recording = new Recording(file);
+ this.append(recording);
+ });
+ } else {
+ this._enumerator.close(null);
+ }
+ });
+ }
+ }
+
+ getIndex(file) {
+ for (var i = 0; i < this.get_n_items(); i++) {
+ if (this.get_item(i).uri === file.get_uri())
+ return i;
+ }
+ return -1;
+ }
+});
diff --git a/src/row.js b/src/row.js
index 7d071d7..eabb151 100644
--- a/src/row.js
+++ b/src/row.js
@@ -1,8 +1,5 @@
-const Gst = imports.gi.Gst;
const Gtk = imports.gi.Gtk;
const GObject = imports.gi.GObject;
-const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
var Info = imports.info;
var Utils = imports.utils;
@@ -18,18 +15,21 @@ var Row = GObject.registerClass({ // eslint-disable-line no-unused-vars
Signals: {
'play': { param_types: [GObject.TYPE_STRING] },
'pause': {},
+ 'deleted': {},
},
}, class Row extends Gtk.ListBoxRow {
- _init(file) {
+ _init(recording) {
super._init({});
- this.file = file;
- this._fileNameLabel.label = file.fileName;
- this._fileDurationLabel.label = Utils.StringUtils.formatTime(file.duration / Gst.SECOND);
+ this._fileNameLabel.label = recording.name;
+
+ recording.connect('notify::duration', () => {
+ this._fileDurationLabel.label = Utils.Time.formatTime(recording.duration);
+ });
this._playButton.connect('clicked', () => {
this.setState(RowState.PLAYING);
- this.emit('play', this.file.uri);
+ this.emit('play', recording.uri);
});
this._pauseButton.connect('clicked', () => {
@@ -37,10 +37,10 @@ var Row = GObject.registerClass({ // eslint-disable-line no-unused-vars
this.emit('pause');
});
- this._infoButton.connect('clicked', () => (new Info.InfoDialog(file)).show());
+ this._infoButton.connect('clicked', () => (new Info.InfoDialog(recording)).show());
this._deleteButton.connect('clicked', () => {
- let gioFile = Gio.File.new_for_uri(file.uri);
- gioFile.trash_async(GLib.PRIORITY_DEFAULT, null, null);
+ recording.delete();
+ this.emit('deleted');
});
}
diff --git a/src/utils.js b/src/utils.js
index f17103f..66529a9 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -24,8 +24,26 @@ const GLib = imports.gi.GLib;
const _TIME_DIVISOR = 60;
-var DisplayTime = class DisplayTime {
- getDisplayTime(mtime) {
+var Time = { // eslint-disable-line no-unused-vars
+ formatTime: unformattedTime => {
+ this.unformattedTime = unformattedTime;
+ let seconds = Math.floor(this.unformattedTime);
+ let hours = parseInt(seconds / Math.pow(_TIME_DIVISOR, 2));
+ let hoursString = '';
+
+ if (hours > 10)
+ hoursString = `${hours}:`;
+ else if (hours < 10 && hours > 0)
+ hoursString = `0${hours}:`;
+
+ let minuteString = parseInt(seconds / _TIME_DIVISOR) % _TIME_DIVISOR;
+ let secondString = parseInt(seconds % _TIME_DIVISOR);
+ let timeString = `${hoursString + (minuteString < 10 ? `0${minuteString}` :
minuteString)}:${secondString < 10 ? `0${secondString}` : secondString}`;
+
+ return timeString;
+ },
+
+ getDisplayTime: mtime => {
let text = '';
let DAY = 86400000000;
let now = GLib.DateTime.new_now_local();
@@ -63,27 +81,5 @@ var DisplayTime = class DisplayTime {
years).format(years);
}
return text;
- }
-
-};
-
-
-var StringUtils = { // eslint-disable-line no-unused-vars
- formatTime: unformattedTime => {
- this.unformattedTime = unformattedTime;
- let seconds = Math.floor(this.unformattedTime);
- let hours = parseInt(seconds / Math.pow(_TIME_DIVISOR, 2));
- let hoursString = '';
-
- if (hours > 10)
- hoursString = `${hours}:`;
- else if (hours < 10 && hours > 0)
- hoursString = `0${hours}:`;
-
- let minuteString = parseInt(seconds / _TIME_DIVISOR) % _TIME_DIVISOR;
- let secondString = parseInt(seconds % _TIME_DIVISOR);
- let timeString = `${hoursString + (minuteString < 10 ? `0${minuteString}` :
minuteString)}:${secondString < 10 ? `0${secondString}` : secondString}`;
-
- return timeString;
},
};
diff --git a/src/waveform.js b/src/waveform.js
index 68bc92e..d88c954 100644
--- a/src/waveform.js
+++ b/src/waveform.js
@@ -54,13 +54,10 @@ var WaveForm = class WaveForm {
this.waveType = WaveType.RECORD;
}
-
-
this.drawing = Gtk.DrawingArea.new();
if (this.waveType === WaveType.RECORD) {
- this.drawing.set_property('valign', Gtk.Align.FILL);
this.drawing.set_property('hexpand', true);
- this._grid.attach(this.drawing, 2, 0, 3, 2);
+ this._grid.attach(this.drawing, 1, 0, 1, 1);
} else {
this.drawing.set_property('valign', Gtk.Align.FILL);
this.drawing.set_property('hexpand', true);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]