From 4421c6f9c3dac71b4d3dac29fe9522ed0f7e50b0 Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sat, 9 Jan 2021 22:02:49 +0100 Subject: [PATCH] Add indicator icon for models marked for later recording --- .../ctbrec/ui/controls/PausedIndicator.java | 34 ------ .../ui/controls/RecordingIndicator.java | 37 +++++++ .../main/java/ctbrec/ui/tabs/ThumbCell.java | 86 ++++++++++----- .../java/ctbrec/ui/tabs/ThumbOverviewTab.java | 98 +++++++++++++----- client/src/main/resources/bookmark-new-16.png | Bin 0 -> 1425 bytes client/src/main/resources/bookmark-new.png | Bin 0 -> 785 bytes .../resources/media-playback-pause-16.png | Bin 0 -> 1400 bytes .../main/resources/media-playback-pause.png | Bin 0 -> 718 bytes client/src/main/resources/media-record-16.png | Bin 0 -> 1445 bytes client/src/main/resources/media-record.png | Bin 0 -> 1203 bytes 10 files changed, 171 insertions(+), 84 deletions(-) delete mode 100644 client/src/main/java/ctbrec/ui/controls/PausedIndicator.java create mode 100644 client/src/main/java/ctbrec/ui/controls/RecordingIndicator.java create mode 100644 client/src/main/resources/bookmark-new-16.png create mode 100644 client/src/main/resources/bookmark-new.png create mode 100644 client/src/main/resources/media-playback-pause-16.png create mode 100644 client/src/main/resources/media-playback-pause.png create mode 100644 client/src/main/resources/media-record-16.png create mode 100644 client/src/main/resources/media-record.png diff --git a/client/src/main/java/ctbrec/ui/controls/PausedIndicator.java b/client/src/main/java/ctbrec/ui/controls/PausedIndicator.java deleted file mode 100644 index 482d8d08..00000000 --- a/client/src/main/java/ctbrec/ui/controls/PausedIndicator.java +++ /dev/null @@ -1,34 +0,0 @@ -package ctbrec.ui.controls; - -import ctbrec.ui.PauseIcon; -import javafx.scene.Cursor; -import javafx.scene.control.Tooltip; -import javafx.scene.layout.StackPane; -import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; -import javafx.scene.shape.Rectangle; - -public class PausedIndicator extends StackPane { - - private PauseIcon pausedIcon; - private Rectangle clickPanel; - - public PausedIndicator(int size, Color color) { - setMaxSize(size, size); - - pausedIcon = new PauseIcon(color, size); - pausedIcon.setVisible(false); - clickPanel = new Rectangle(size, size); - clickPanel.setCursor(Cursor.HAND); - clickPanel.setFill(Paint.valueOf("#00000000")); - getChildren().add(pausedIcon); - getChildren().add(clickPanel); - - pausedIcon.visibleProperty().bindBidirectional(visibleProperty()); - clickPanel.onMouseClickedProperty().bindBidirectional(onMouseClickedProperty()); - - Tooltip tooltip = new Tooltip("Resume Recording"); - Tooltip.install(clickPanel, tooltip); - } -} - diff --git a/client/src/main/java/ctbrec/ui/controls/RecordingIndicator.java b/client/src/main/java/ctbrec/ui/controls/RecordingIndicator.java new file mode 100644 index 00000000..ed07aa1b --- /dev/null +++ b/client/src/main/java/ctbrec/ui/controls/RecordingIndicator.java @@ -0,0 +1,37 @@ +package ctbrec.ui.controls; + +import javafx.scene.Cursor; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Paint; +import javafx.scene.shape.Rectangle; + +public class RecordingIndicator extends StackPane { + + private ImageView icon; + private Rectangle clickPanel; + + public RecordingIndicator(int size) { + setMaxSize(size, size); + + icon = new ImageView(); + icon.setVisible(false); + icon.prefHeight(size); + icon.prefWidth(size); + icon.maxHeight(size); + icon.maxWidth(size); + clickPanel = new Rectangle(size, size); + clickPanel.setCursor(Cursor.HAND); + clickPanel.setFill(Paint.valueOf("#00000000")); + getChildren().add(icon); + getChildren().add(clickPanel); + + icon.visibleProperty().bindBidirectional(visibleProperty()); + } + + public void setImage(Image img) { + icon.setImage(img); + } +} + diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java index 3899e3d1..1c6455b9 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java @@ -31,7 +31,7 @@ import ctbrec.ui.SiteUiFactory; import ctbrec.ui.StreamSourceSelectionDialog; import ctbrec.ui.action.PlayAction; import ctbrec.ui.controls.Dialogs; -import ctbrec.ui.controls.PausedIndicator; +import ctbrec.ui.controls.RecordingIndicator; import ctbrec.ui.controls.StreamPreview; import javafx.animation.FadeTransition; import javafx.animation.FillTransition; @@ -51,6 +51,7 @@ import javafx.scene.control.ContextMenu; import javafx.scene.control.Tooltip; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; @@ -72,6 +73,11 @@ public class ThumbCell extends StackPane { private static final Logger LOG = LoggerFactory.getLogger(ThumbCell.class); private static final Duration ANIMATION_DURATION = new Duration(250); + private static Image imgRecordIndicator = new Image(ThumbCell.class.getResource("/media-record-16.png").toExternalForm()); + private static Image imgPauseIndicator = new Image(ThumbCell.class.getResource("/media-playback-pause-16.png").toExternalForm()); + private static Image imgBookmarkIndicator = new Image(ThumbCell.class.getResource("/bookmark-new-16.png").toExternalForm()); + + private ModelRecordingState modelRecordingState = ModelRecordingState.NOT; private Model model; private StreamPreview streamPreview; private ImageView iv; @@ -85,8 +91,8 @@ public class ThumbCell extends StackPane { private Text topic; private Text resolutionTag; private Recorder recorder; - private Circle recordingIndicator; - private PausedIndicator pausedIndicator; + private RecordingIndicator recordingIndicator; + private Tooltip recordingIndicatorTooltip; private StackPane previewTrigger; private int index = 0; ContextMenu popup; @@ -178,22 +184,15 @@ public class ThumbCell extends StackPane { StackPane.setMargin(resolutionTag, new Insets(2, 4, 2, 2)); getChildren().add(resolutionTag); - recordingIndicator = new Circle(8); - recordingIndicator.setFill(colorRecording); + recordingIndicator = new RecordingIndicator(16); recordingIndicator.setCursor(Cursor.HAND); - recordingIndicator.setOnMouseClicked(e -> pauseResumeAction(true)); - Tooltip tooltip = new Tooltip("Pause Recording"); - Tooltip.install(recordingIndicator, tooltip); + recordingIndicator.setOnMouseClicked(this::recordingInidicatorClicked); + recordingIndicatorTooltip = new Tooltip("Pause Recording"); + Tooltip.install(recordingIndicator, recordingIndicatorTooltip); StackPane.setMargin(recordingIndicator, new Insets(3)); StackPane.setAlignment(recordingIndicator, Pos.TOP_LEFT); getChildren().add(recordingIndicator); - pausedIndicator = new PausedIndicator(16, colorRecording); - pausedIndicator.setOnMouseClicked(e -> pauseResumeAction(false)); - StackPane.setMargin(pausedIndicator, new Insets(3)); - StackPane.setAlignment(pausedIndicator, Pos.TOP_LEFT); - getChildren().add(pausedIndicator); - if (Config.getInstance().getSettings().livePreviews) { getChildren().add(createPreviewTrigger()); } @@ -231,6 +230,21 @@ public class ThumbCell extends StackPane { update(); } + private void recordingInidicatorClicked(MouseEvent evt) { + switch(modelRecordingState) { + case RECORDING: + pauseResumeAction(true); + break; + case PAUSED: + pauseResumeAction(false); + break; + case BOOKMARKED: + recordLater(false); + break; + default: + } + } + private Node createPreviewTrigger() { int s = 32; previewTrigger = new StackPane(); @@ -293,7 +307,6 @@ public class ThumbCell extends StackPane { streamPreview.stop(); } recordingIndicator.setVisible(!visible); - pausedIndicator.setVisible(!visible); if (!visible) { updateRecordingIndicator(); } @@ -445,17 +458,32 @@ public class ThumbCell extends StackPane { c = mouseHovering ? colorHighlight : colorNormal; } nameBackground.setFill(c); - updateRecordingIndicator(); } private void updateRecordingIndicator() { if (recording) { - recordingIndicator.setVisible(!model.isSuspended()); - pausedIndicator.setVisible(model.isSuspended()); + recordingIndicator.setVisible(true); + if (model.isSuspended()) { + modelRecordingState = ModelRecordingState.PAUSED; + recordingIndicator.setImage(imgPauseIndicator); + recordingIndicatorTooltip.setText("Resume Recording"); + } else { + modelRecordingState = ModelRecordingState.RECORDING; + recordingIndicator.setImage(imgRecordIndicator); + recordingIndicatorTooltip.setText("Pause Recording"); + } } else { - recordingIndicator.setVisible(false); - pausedIndicator.setVisible(false); + if (model.isMarkedForLaterRecording()) { + recordingIndicator.setVisible(true); + modelRecordingState = ModelRecordingState.BOOKMARKED; + recordingIndicator.setImage(imgBookmarkIndicator); + recordingIndicatorTooltip.setText("Forget Model"); + } else { + recordingIndicator.setVisible(false); + modelRecordingState = ModelRecordingState.NOT; + recordingIndicator.setImage(null); + } } } @@ -562,9 +590,9 @@ public class ThumbCell extends StackPane { }); } - void recordLater() { - model.setMarkedForLaterRecording(true); - startStopAction(true); + void recordLater(boolean recordLater) { + model.setMarkedForLaterRecording(recordLater); + startStopAction(recordLater); } public Model getModel() { @@ -577,7 +605,6 @@ public class ThumbCell extends StackPane { this.model.setPreview(model.getPreview()); this.model.setTags(model.getTags()); this.model.setUrl(model.getUrl()); - this.model.setSuspended(recorder.isSuspended(model)); update(); } @@ -591,9 +618,11 @@ public class ThumbCell extends StackPane { private void update() { model.setSuspended(recorder.isSuspended(model)); + model.setMarkedForLaterRecording(recorder.isMarkedForLaterRecording(model)); setRecording(recorder.isTracked(model)); + updateRecordingIndicator(); setImage(model.getPreview()); - String txt = recording ? " " : ""; + String txt = (modelRecordingState != ModelRecordingState.NOT) ? " " : ""; txt += model.getDescription() != null ? model.getDescription() : ""; topic.setText(txt); @@ -693,4 +722,11 @@ public class ThumbCell extends StackPane { model.setMarkedForLaterRecording(false); startStopAction(true); } + + private enum ModelRecordingState { + RECORDING, + PAUSED, + BOOKMARKED, + NOT + } } diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java index ae0a1b9b..25bd867d 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java @@ -1,5 +1,31 @@ package ctbrec.ui.tabs; +import static ctbrec.ui.controls.Dialogs.*; + +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import ctbrec.Config; import ctbrec.Model; import ctbrec.event.EventBusHolder; @@ -7,12 +33,24 @@ import ctbrec.recorder.Recorder; import ctbrec.sites.Site; import ctbrec.sites.mfc.MyFreeCamsClient; import ctbrec.sites.mfc.MyFreeCamsModel; -import ctbrec.ui.*; +import ctbrec.ui.AutosizeAlert; +import ctbrec.ui.DesktopIntegration; +import ctbrec.ui.SiteUiFactory; +import ctbrec.ui.TipDialog; +import ctbrec.ui.TokenLabel; import ctbrec.ui.action.IgnoreModelsAction; import ctbrec.ui.action.OpenRecordingsDir; import ctbrec.ui.action.SetStopDateAction; -import ctbrec.ui.controls.*; -import javafx.animation.*; +import ctbrec.ui.controls.CustomMouseBehaviorContextMenu; +import ctbrec.ui.controls.FasterVerticalScrollPaneSkin; +import ctbrec.ui.controls.SearchBox; +import ctbrec.ui.controls.SearchPopover; +import ctbrec.ui.controls.SearchPopoverTreeList; +import javafx.animation.FadeTransition; +import javafx.animation.Interpolator; +import javafx.animation.ParallelTransition; +import javafx.animation.ScaleTransition; +import javafx.animation.TranslateTransition; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -28,24 +66,34 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.Parent; -import javafx.scene.control.*; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; -import javafx.scene.input.*; -import javafx.scene.layout.*; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.ContextMenuEvent; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; import javafx.scene.transform.Transform; import javafx.util.Duration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.text.DecimalFormat; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - -import static ctbrec.ui.controls.Dialogs.showError; public class ThumbOverviewTab extends Tab implements TabSelectionListener { private static final Logger LOG = LoggerFactory.getLogger(ThumbOverviewTab.class); @@ -441,7 +489,10 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { MenuItem addPaused = new MenuItem("Add in paused state"); addPaused.setOnAction(e -> addPaused(getSelectedThumbCells(cell))); MenuItem recordLater = new MenuItem("Record Later"); - recordLater.setOnAction(e -> recordLater(getSelectedThumbCells(cell))); + recordLater.setOnAction(e -> recordLater(getSelectedThumbCells(cell), true)); + MenuItem removeRecordLater = new MenuItem("Forget Model"); + removeRecordLater.setOnAction(e -> recordLater(getSelectedThumbCells(cell), false)); + MenuItem addRemoveBookmark = recorder.isMarkedForLaterRecording(model) ? removeRecordLater : recordLater; MenuItem pause = new MenuItem("Pause Recording"); pause.setOnAction(e -> pauseResumeAction(getSelectedThumbCells(cell), true)); @@ -476,10 +527,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { if (modelIsTrackedByRecorder) { contextMenu.getItems().addAll(pauseResume, recordLater); } else { - contextMenu.getItems().addAll(recordUntil, addPaused); - if (!recorder.isMarkedForLaterRecording(model)) { - contextMenu.getItems().add(recordLater); - } + contextMenu.getItems().addAll(recordUntil, addPaused, addRemoveBookmark); } contextMenu.getItems().add(new SeparatorMenuItem()); if (site.supportsFollow()) { @@ -500,9 +548,9 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { return contextMenu; } - private void recordLater(List list) { + private void recordLater(List list, boolean recordLater) { for (ThumbCell cell : list) { - cell.recordLater(); + cell.recordLater(recordLater); } } diff --git a/client/src/main/resources/bookmark-new-16.png b/client/src/main/resources/bookmark-new-16.png new file mode 100644 index 0000000000000000000000000000000000000000..d50f515ac91a165291fc58825f8c441776b77769 GIT binary patch literal 1425 zcmV;C1#bF@P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3vruHzsKh5xgPSpv2(hUM^-W(TwUIV5R&=gw7| zNC|3)c=_P(kkpMozo+|!i&AD6)KbhbdR!rg%mok0zpioAdmH(%-5(bncXB^=Fls?9 zd!vP;SC00_`1q``&<`D?-zLa241W!5xnd zytyPGwn7XE5co)<6v-R25e4A{Kn2QK0#^_qRqhbUK_r4rf{zdzbBwmJth~45sDO`3 z6a$+q1+YR;_{Tzmhl+{@RgG$zG;48DVu%`Jw7AY(F|lB3(ae%%D@jsFnqsn)Qcfjv z792^)aanb8>uzUp48B4wieo!p!J^7 z#SFwa5Qy6%07LU)<`ad$i`-)7Gvib!L!>S?oqTZ=fiMhWo%Ce)B6pgbL#{t@<1^&k zLU#i>c0;~#`+-_tZ^E__+fU)jsTZ6+^p8|H6(pPY2alQSforQWMtd}$t=-iL6NI*S zJ;R_dVS=rQxCyC># zrc=I<^H}A)#aXM?SnHnrh2es}yu@`{Lr7r(i;y5fK@AmDVIx7iPKt#LohN<#G1o7V zOCeVUj2!dWfCkz1ga5(r*;>VkaW5&H1iD`w=VKTM?E=lZ<9r`GPV)o^J_A>J+rQBO zrawuqx3%~YFt80=T(>o454hX`2A>SslwB!EODGnB_cQvYJP^4B`c}QUwa#(+0Ay)a z=^NnS5Ev;@_L|STdphU#Z%=D}KlrV3c3^81=l}o!24YJ`L;wH)0002_L%V+f000Sa zNLh0L01ejw01ejxLMWSf0001xNklSAz2(69dD@A*Bumo>UElLaLMR}98%(f7ui-ey z8izVyhz0r$z#X9iI(|$Gw7}ni0yiAXTGTDYAD-ok9X2>&j5%f)GyxZ^u*W$GA+P#b fnr<<|wA=$v#MmB{xDV{g00000NkvXXu0mjfhk%@k literal 0 HcmV?d00001 diff --git a/client/src/main/resources/bookmark-new.png b/client/src/main/resources/bookmark-new.png new file mode 100644 index 0000000000000000000000000000000000000000..90b9daad381b56e5c3a8397496163c0df0f26692 GIT binary patch literal 785 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU~J2Db`J1#c2+1T%1_J8No8Qr zm{>c}*5h!1NUMMJQY}$OYmvee0dsXax;XTrT9raLwmPlmQ`7(3tj6ov)xG#ZRKbVz zjjtX&TC=)&wF1Y#h8;UCHFtS*ephW3GmNX))BpLM<(_i+2kWQL%qr_)T$Lud(k13Z zN_gu7?V1;E_GtnWXRJKmnItstYpMU;kaEL$Pw#$D|Egs6WRf>n=+9haj1 zdCAWBr?U6jrA6)z_st3l?_PRh`=E%u!{+5AMa!UuY4-Ek@11`!d((jfx)(M-JGZv7 z?=riB?`E%i4D9U(JQ_D$x4n1ws@?Yb>RF$EGd5l=T6@&knI9N2Y)RhkE zaB^>EX>4U6ba`-PAZ2)IW&i+q+P#%)lH({4g#UAjJp%Qj;5dj!#NJ?!KZzu}XJMGIHF*&clqb${Lpolgo6KQLNB zD@Uj6`Bl#T+xT>E5$M4OvR@|1Jq`by*z4KPk^iS?=sm~Ba?anJJ0SVvmTh zdOG(Cx|kOSTH7e=iD3Xj^WZ zU(|Sai6XZ_3<(g#L}HXEIV3Xk^c&7q3~eX3Hsi&bj1T zxCoAY}apPym zg@x_{avX;I!tDXIzHY*{6FW}f+S4dFeQi|EmAAG98KbTDjKQzA6Pvup=?WiFMDknQ z_rr$Qbv)8DaQZLN14CY;C(dw<9?sz!J!yt(^uXEI=-C5Zq310hJ<@|f*XVh}N00UJ z7Ov6rvXB0x=bP8a+dlfU9vR^pJums_Gd-h)YxKO}qtErceT}^Bqp$S5d5yg7qp$UR z>+k4gA3dYz8-GVH`{+46f6qtH>UkFb>?QmFr%9&%UQDf+0004mX+uL$Nkc;*aB^>E zX>4Tx0C=2zkv&MmP!xqvQ>7{uhjx(SkfAzR5EXIMDionYs1;guFnQ@8G%+M8E{=k0 z!NH%!s)LKOt`4q(Aov5~=H{g6A|>9J6k5c1;qgAsyXWxUeSpxYGR^8512o+>GpVGQ z%dd!`R|L?D2x17x%ra&rDGlHHx~Fccy9Cej@B6d*)q=%z@3D;ex)r#C2LjNMQkskRU=q4HZ;jBSE`PiiHfFCw=@e*DsMvAy);A9P`+K z2HEw4|H1FsTE&TRFDaY^x?ddUV;BhS0?oSPd>=bb^8^S!16O+6ztI4uKS{5*wfGS* zunk;Xw>4!CxZD8-pA6ZQT`5RQC>DYDGy0}H5V-~VR=v5k&T;wxWNB9E8{ps&7%5Tq zn$Np?I_LIpPiuZZ_^onwU~3fU00006VoOIv00000008+zyMF)x010qNS#tmY4c7nw z4c7reD4Tcy004kVL_t(I%k9Z=_igyApf(NaRo5R@6<&4B2rGYvZ+u|Wn%nH{J} znHDL~5b5EL7R8c}*5h!1NUMMFQZ3Q;vI&nSEVPOg5G}l-C9=?Ig=kc%LFG$%6GIhEy}qXGg9qmy zUDe#Zc^%)nCWRl&kDfhS@E@Z1k2E$$yh>Qw9C`CfhkEDZRm+0+ zP52z~bkEVq)z>0k&->H*uxa0(Bc)N!9*KVHcwK*@ zw_-SJkId&A4Qw~RHvd2P{$|wC&O&|7IV`*4Wu7NXaJ*$YyX$d{ytUtF77jb+@T%MU zFET8%_guey>kmPL4ZJZi+f7sXcidrQo6mD|O01@bw}x2bcjI5nYy@_){tDZ>bL+Xn zUkoXkVK1d0JP?r34E#3h{O)S2=il=Ev+L}CtSu_LH|O6{V6?C$dAqv+X(0INyt^Jq zaTa()76W7OItVj5Y0Rzw3f}W{aSW-r_4aZgFM|SygQMwW#SR}1>r4*&IaT5e$G&N> zf=mE{3g5f321?IPGFPS9?)?Al_iXtevl&<#7z7xY92htl7!?>;29$&B2nHzl9_9L& V zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=HElH4E+hTl0wj(|1<$H6RBxj~MfAKUGo%#!KU zOjTYQsx1nHB=iZp!}#@ch978@NrRf_R8op)TC{M*Ajf+fr#$8;>i)bnI-eBYU0_Io zlw;EMT$OYFrk^eeL+>n*z1kp`8-D57>p9Pn|A?rh%g6mV=WouQ=N!lBswSi%9fvwx zgqs;CZpf1C+m=Dc&oK7A7xWx!Y^1Tr7B}=pg_tBxQtE*!O&Zi88#TnJJlG+b8_PbI z#kp{kC?vW%O?D~LB@0XAAtD-tuUKgJTXuhqGCX&JDie$mw*0k+&lDc%bGC>a5#jW7 z<_d8!FAlWQDC-F|0HJwuvpvDLezoudtbm~HY0fxcjoV>jGrHH7>;)juGsvU9$orzk zdzC1B8-gJLf|y8*5=CcrA{EX6R1rCg@&*EA#vMVjiX^bfs3Z8s9;aQGjgNU;74R`h z;$Tyx0+yw-wA#5#*KR#^@41&= z2Mv@`7&>gE;UkYS>O`$gnL2Hz=`+tV>qYIP`lkN_H9D#BPHO4-MGdp=%g}Cu)_cYl zGZ14X5cfp@1KX$y-8M6+q?pUEh@n>m(2EFS z2*}JbW+f>N-}<_zZmPQk&+_m4v-;J7#ejfFJi`prCSE6=+O!SM`@~UJmQ~_&;!%?> zNc_lk#p5^5C6@)B88x$+IpQd>Sn6PpOyv13o)>!MF{Dt9y zzP!YBT0=--0gI3zLO~4`RAD1QyH1LQ44o%^{4v)rkxL<01&kc?*nkGv^@IPx@7Y?# ziE%F}oCLaG9Oq*g2<-yRy5oEwJ5KWi2tET>dfUIz0H!}lueY`M5iqa~TwJ#`We>RA z0S2E8*_2%=NJ}Udf%h}|raTb21^QOKxwX!5`T%5UR_Pny;1C!oQTCe8yL&q4_HR#X zen0rFa&};A6zBi|00v@9M??Ss00000`9r&Z00009a7bBm000fw000fw0YWI7cmMzZ z>q$gGR5;76(=kp0Q4q%Q-#&Xo#U0dwglr)tR&@5Bz<385y@Qbp*xS91lE#ow7&*gM zgqpB6vxcmRWYMpDZ~ouRo0(T=>3uRe#{fh0;&_84R%OoH!}#I=Ji|5aaf3cmT<=j~ zju{qZ&bx1efN$}L%R}RqYOFEETbc8&$uPnbu6}`=gclJzf+F7hjJqRnyOLKtq-fZ< z1KdSVuDl8LLv0-%wxDIBOVz*!L z*}-6qS()>;Y2qT*^W#V*btIYw^G~1YFW>nK+`CGVFp1yg00000NkvXXu0mjf4`#NV literal 0 HcmV?d00001 diff --git a/client/src/main/resources/media-record.png b/client/src/main/resources/media-record.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a507cb2a258ff51b3faeb24c68c4c0354bd90f GIT binary patch literal 1203 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU~J2Db`J1#c2+1T%1_J8No8Qr zm{>c}*5h!1NUMMJQY}$OYmvee0dsXax;XTrT9raLwmPlmQ`7(3tj6ov)xG#ZRKbVz zjjtX&TC=)&wF1Y#h8;UCHFtS*ephW3GmNX))BpLM<(_i+2kWQL%qr_)T$Lud(k13Z zN_gu7?V1;E_GtnWXRJKmnItstYpMU;kaEL$Pw#$D|Egs6WRf>n=+9haj1 zdCAWBr?U6jrA6)z_st3l?_PRh`=E%u!{+5AMa!UuY4-Ek@11`!d((jfx)(M-JGZv7 z?=riB?`E%i4D9U(JQ_D$x4n1ws@?Yb>RF$EGd5l=T6@&knI9N2Y)RhkE?0b!yK+|{KCV_qVoLBZpoZkG;e#e{OUwsUIWqY5Q2^{*a z+X#|s`B3Yv(DFW-NwMa>5XZyc(;PVNZ)Z7d_3-}>&n5i%Gw$Ez5ODhEx`hAp+HOII zudn4;oqp_7m57MD&$0V{Id@2A!}iC8-YI6+wsbM{?Ykb|84Jm$ETVf*EmelDe&wZ%Nw8F%mK@;}bWZ*R5kdP{r%O{o>x=)f^2hRfppXSx#^l+MQVn z3>)qjcmJ;DYGCr9GGMunu{`U-fF)e!=REOy^o90#`}WR zAAu<~;v4)upQYZkJoRspVvQ;9gO$8nSk{L%%u~G}wl9jYO4u>^gBlBmVhb=l*Vs*} zlRCck+y6eJ&pW=$JP!DE^5)hV(^J3K?430sY|YzMGEEt^K7XfNN_cyZqnIhfMmb~N u$5`$QL2RcNmTNlXDpqmIAQBpw_3OEOrWQ}*^|1U8Aik%opUXO@geCw~Hw7dB literal 0 HcmV?d00001