Opera8 commited on
Commit
8a41149
·
verified ·
1 Parent(s): 41fb562

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -61
app.py CHANGED
@@ -1005,7 +1005,7 @@ class PresetGallery(gr.HTML):
1005
 
1006
 
1007
  ####################################################################################################
1008
- ### PART 16: Custom Component - AudioDropUpload
1009
  ####################################################################################################
1010
  class AudioDropUpload(gr.HTML):
1011
  """
@@ -1015,7 +1015,7 @@ class AudioDropUpload(gr.HTML):
1015
  - The hidden gr.Audio must be type="filepath" (or whatever you need).
1016
  """
1017
  def __init__(self, target_audio_elem_id: str, value=None, **kwargs):
1018
- uid = uuid.uuid4().hex
1019
 
1020
  html_template = f"""
1021
  <div class="aud-wrap" data-aud="{uid}">
@@ -1042,12 +1042,12 @@ class AudioDropUpload(gr.HTML):
1042
  # - finds the hidden gr.Audio upload <input type=file> inside the component with elem_id=target_audio_elem_id
1043
  # - sets the selected file onto it (DataTransfer) and dispatches change
1044
  js_on_load = """
1045
- (() => {
1046
  // Helper: access Gradio shadow DOM safely
1047
- function grRoot() {
1048
  const ga = document.querySelector("gradio-app");
1049
  return (ga && ga.shadowRoot) ? ga.shadowRoot : document;
1050
- }
1051
  const root = grRoot();
1052
  const wrap = element.querySelector(".aud-wrap");
1053
  const drop = element.querySelector(".aud-drop");
@@ -1057,53 +1057,47 @@ class AudioDropUpload(gr.HTML):
1057
  const label = element.querySelector(".aud-filelabel");
1058
  const TARGET_ID = "__TARGET_ID__";
1059
  let currentUrl = null;
1060
-
1061
- function findHiddenAudioFileInput() {
1062
  const host = root.querySelector("#" + CSS.escape(TARGET_ID));
1063
  if (!host) return null;
1064
  // Gradio's Audio component contains an <input type=file> for upload.
1065
  // This selector works in most Gradio 3/4 themes.
1066
- const inp = host.querySelector('input');
1067
  return inp;
1068
- }
1069
-
1070
- function showDrop() {
1071
  drop.style.display = "";
1072
  row.style.display = "none";
1073
  label.style.display = "none";
1074
  label.textContent = "";
1075
- }
1076
-
1077
- function showPlayer(filename) {
1078
  drop.style.display = "none";
1079
  row.style.display = "flex";
1080
- if (filename) {
1081
  label.textContent = "فایل بارگذاری شده: " + filename;
1082
  label.style.display = "block";
1083
- }
1084
- }
1085
-
1086
- function clearPreview() {
1087
  player.pause();
1088
  player.removeAttribute("src");
1089
  player.load();
1090
- if (currentUrl) {
1091
  URL.revokeObjectURL(currentUrl);
1092
  currentUrl = null;
1093
- }
1094
- }
1095
-
1096
- function clearHiddenGradioAudio() {
1097
  const fileInput = findHiddenAudioFileInput();
1098
  if (!fileInput) return;
1099
  // Clear file input (works by replacing its files with empty DataTransfer)
1100
  fileInput.value = "";
1101
  const dt = new DataTransfer();
1102
  fileInput.files = dt.files;
1103
- fileInput.dispatchEvent(new Event("input", { bubbles: true }));
1104
- fileInput.dispatchEvent(new Event("change", { bubbles: true }));
1105
- }
1106
-
1107
  function clearAll() {
1108
  clearPreview();
1109
 
@@ -1117,18 +1111,18 @@ class AudioDropUpload(gr.HTML):
1117
  showDrop();
1118
  }
1119
 
1120
- function loadFileToPreview(file) {
1121
  if (!file) return;
1122
- if (!file.type || !file.type.startsWith("audio/")) {
1123
  alert("لطفا یک فایل صوتی انتخاب کنید.");
1124
  return;
1125
- }
1126
  clearPreview();
1127
  currentUrl = URL.createObjectURL(file);
1128
  player.src = currentUrl;
1129
  showPlayer(file.name);
1130
- }
1131
-
1132
  function pushFileIntoHiddenGradioAudio(file) {
1133
  const fileInput = findHiddenAudioFileInput();
1134
  if (!fileInput) {
@@ -1144,15 +1138,14 @@ class AudioDropUpload(gr.HTML):
1144
  fileInput.files = dt.files;
1145
 
1146
  // Trigger Gradio listeners
1147
- fileInput.dispatchEvent(new Event("input", { bubbles: true }));
1148
- fileInput.dispatchEvent(new Event("change", { bubbles: true }));
1149
  }
1150
 
1151
- function handleFile(file) {
1152
  loadFileToPreview(file);
1153
  pushFileIntoHiddenGradioAudio(file);
1154
- }
1155
-
1156
  // Click-to-browse uses a *local* ephemeral input (not Gradio’s),
1157
  // then we forward to hidden gr.Audio.
1158
  const localPicker = document.createElement("input");
@@ -1160,40 +1153,33 @@ class AudioDropUpload(gr.HTML):
1160
  localPicker.accept = "audio/*";
1161
  localPicker.style.display = "none";
1162
  wrap.appendChild(localPicker);
1163
-
1164
- localPicker.addEventListener("change", () => {
1165
- const f = localPicker.files && localPicker.files;
1166
  if (f) handleFile(f);
1167
  localPicker.value = "";
1168
- });
1169
-
1170
  drop.addEventListener("click", () => localPicker.click());
1171
-
1172
- drop.addEventListener("keydown", (e) => {
1173
- if (e.key === "Enter" || e.key === " ") {
1174
  e.preventDefault();
1175
  localPicker.click();
1176
- }
1177
- });
1178
-
1179
  removeBtn.addEventListener("click", clearAll);
1180
-
1181
- // Drag & drop.forEach(evt => {
1182
- drop.addEventListener(evt, (e) => {
1183
  e.preventDefault();
1184
  e.stopPropagation();
1185
- });
1186
- });
1187
-
1188
  drop.addEventListener("dragover", () => drop.classList.add("dragover"));
1189
  drop.addEventListener("dragleave", () => drop.classList.remove("dragover"));
1190
-
1191
- drop.addEventListener("drop", (e) => {
1192
  drop.classList.remove("dragover");
1193
- const f = e.dataTransfer.files && e.dataTransfer.files;
1194
  if (f) handleFile(f);
1195
- });
1196
-
1197
  // init
1198
  showDrop();
1199
 
@@ -1232,7 +1218,8 @@ class AudioDropUpload(gr.HTML):
1232
  };
1233
  requestAnimationFrame(syncFromProps);
1234
 
1235
- })();
 
1236
  """
1237
  js_on_load = js_on_load.replace("__TARGET_ID__", target_audio_elem_id)
1238
 
 
1005
 
1006
 
1007
  ####################################################################################################
1008
+ ### PART 16: Custom Component - AudioDropUpload (FIXED)
1009
  ####################################################################################################
1010
  class AudioDropUpload(gr.HTML):
1011
  """
 
1015
  - The hidden gr.Audio must be type="filepath" (or whatever you need).
1016
  """
1017
  def __init__(self, target_audio_elem_id: str, value=None, **kwargs):
1018
+ uid = uuid.uuid4().hex[:8]
1019
 
1020
  html_template = f"""
1021
  <div class="aud-wrap" data-aud="{uid}">
 
1042
  # - finds the hidden gr.Audio upload <input type=file> inside the component with elem_id=target_audio_elem_id
1043
  # - sets the selected file onto it (DataTransfer) and dispatches change
1044
  js_on_load = """
1045
+ (() => {{
1046
  // Helper: access Gradio shadow DOM safely
1047
+ function grRoot() {{
1048
  const ga = document.querySelector("gradio-app");
1049
  return (ga && ga.shadowRoot) ? ga.shadowRoot : document;
1050
+ }}
1051
  const root = grRoot();
1052
  const wrap = element.querySelector(".aud-wrap");
1053
  const drop = element.querySelector(".aud-drop");
 
1057
  const label = element.querySelector(".aud-filelabel");
1058
  const TARGET_ID = "__TARGET_ID__";
1059
  let currentUrl = null;
1060
+ function findHiddenAudioFileInput() {{
 
1061
  const host = root.querySelector("#" + CSS.escape(TARGET_ID));
1062
  if (!host) return null;
1063
  // Gradio's Audio component contains an <input type=file> for upload.
1064
  // This selector works in most Gradio 3/4 themes.
1065
+ const inp = host.querySelector('input[type="file"]');
1066
  return inp;
1067
+ }}
1068
+ function showDrop() {{
 
1069
  drop.style.display = "";
1070
  row.style.display = "none";
1071
  label.style.display = "none";
1072
  label.textContent = "";
1073
+ }}
1074
+ function showPlayer(filename) {{
 
1075
  drop.style.display = "none";
1076
  row.style.display = "flex";
1077
+ if (filename) {{
1078
  label.textContent = "فایل بارگذاری شده: " + filename;
1079
  label.style.display = "block";
1080
+ }}
1081
+ }}
1082
+ function clearPreview() {{
 
1083
  player.pause();
1084
  player.removeAttribute("src");
1085
  player.load();
1086
+ if (currentUrl) {{
1087
  URL.revokeObjectURL(currentUrl);
1088
  currentUrl = null;
1089
+ }}
1090
+ }}
1091
+ function clearHiddenGradioAudio() {{
 
1092
  const fileInput = findHiddenAudioFileInput();
1093
  if (!fileInput) return;
1094
  // Clear file input (works by replacing its files with empty DataTransfer)
1095
  fileInput.value = "";
1096
  const dt = new DataTransfer();
1097
  fileInput.files = dt.files;
1098
+ fileInput.dispatchEvent(new Event("input", {{ bubbles: true }}));
1099
+ fileInput.dispatchEvent(new Event("change", {{ bubbles: true }}));
1100
+ }}
 
1101
  function clearAll() {
1102
  clearPreview();
1103
 
 
1111
  showDrop();
1112
  }
1113
 
1114
+ function loadFileToPreview(file) {{
1115
  if (!file) return;
1116
+ if (!file.type || !file.type.startsWith("audio/")) {{
1117
  alert("لطفا یک فایل صوتی انتخاب کنید.");
1118
  return;
1119
+ }}
1120
  clearPreview();
1121
  currentUrl = URL.createObjectURL(file);
1122
  player.src = currentUrl;
1123
  showPlayer(file.name);
1124
+
1125
+ }}
1126
  function pushFileIntoHiddenGradioAudio(file) {
1127
  const fileInput = findHiddenAudioFileInput();
1128
  if (!fileInput) {
 
1138
  fileInput.files = dt.files;
1139
 
1140
  // Trigger Gradio listeners
1141
+ fileInput.dispatchEvent(new Event("input", {{ bubbles: true }}));
1142
+ fileInput.dispatchEvent(new Event("change", {{ bubbles: true }}));
1143
  }
1144
 
1145
+ function handleFile(file) {{
1146
  loadFileToPreview(file);
1147
  pushFileIntoHiddenGradioAudio(file);
1148
+ }}
 
1149
  // Click-to-browse uses a *local* ephemeral input (not Gradio’s),
1150
  // then we forward to hidden gr.Audio.
1151
  const localPicker = document.createElement("input");
 
1153
  localPicker.accept = "audio/*";
1154
  localPicker.style.display = "none";
1155
  wrap.appendChild(localPicker);
1156
+ localPicker.addEventListener("change", () => {{
1157
+ const f = localPicker.files && localPicker.files[0];
 
1158
  if (f) handleFile(f);
1159
  localPicker.value = "";
1160
+ }});
 
1161
  drop.addEventListener("click", () => localPicker.click());
1162
+ drop.addEventListener("keydown", (e) => {{
1163
+ if (e.key === "Enter" || e.key === " ") {{
 
1164
  e.preventDefault();
1165
  localPicker.click();
1166
+ }}
1167
+ }});
 
1168
  removeBtn.addEventListener("click", clearAll);
1169
+ // Drag & drop
1170
+ ["dragenter","dragover","dragleave","drop"].forEach(evt => {{
1171
+ drop.addEventListener(evt, (e) => {{
1172
  e.preventDefault();
1173
  e.stopPropagation();
1174
+ }});
1175
+ }});
 
1176
  drop.addEventListener("dragover", () => drop.classList.add("dragover"));
1177
  drop.addEventListener("dragleave", () => drop.classList.remove("dragover"));
1178
+ drop.addEventListener("drop", (e) => {{
 
1179
  drop.classList.remove("dragover");
1180
+ const f = e.dataTransfer.files && e.dataTransfer.files[0];
1181
  if (f) handleFile(f);
1182
+ }});
 
1183
  // init
1184
  showDrop();
1185
 
 
1218
  };
1219
  requestAnimationFrame(syncFromProps);
1220
 
1221
+
1222
+ }})();
1223
  """
1224
  js_on_load = js_on_load.replace("__TARGET_ID__", target_audio_elem_id)
1225