mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-16 04:42:18 +02:00
user edit proxy type
This commit is contained in:
@@ -66,4 +66,5 @@
|
||||
@forward "components/cvs_table";
|
||||
@forward "components/config/config_view";
|
||||
@forward "components/tabset";
|
||||
@forward "components/select";
|
||||
@forward "components/select";
|
||||
@forward "components/form";
|
||||
@@ -0,0 +1,43 @@
|
||||
@use '../../size';
|
||||
|
||||
.tp__form-field {
|
||||
display: flex;
|
||||
gap: var(--gap-default);
|
||||
box-sizing: border-box;
|
||||
min-width: size.$config-field-min-width;
|
||||
|
||||
&__text {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
&__value {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--modest-text-color);
|
||||
padding: var(--padding-small) var(--padding-mini);
|
||||
min-height: 2.5rem;
|
||||
max-height: 2.5rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border: 1px solid var(--input-border-color);
|
||||
border-radius: var(--border-radius);
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__bool {
|
||||
flex-flow: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
color: var(--text-color);
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
@@ -52,48 +52,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.tp__config-field {
|
||||
display: flex;
|
||||
gap: var(--gap-default);
|
||||
box-sizing: border-box;
|
||||
min-width: size.$config-field-min-width;
|
||||
|
||||
&__text {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
&__value {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
background-color: var(--input-background-color);
|
||||
color: var(--modest-text-color);
|
||||
padding: var(--padding-small) var(--padding-mini);
|
||||
min-height: 2.5rem;
|
||||
max-height: 2.5rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border: 1px solid var(--input-border-color);
|
||||
border-radius: var(--border-radius);
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__bool {
|
||||
flex-flow: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
color: var(--text-color);
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tp__config-view-page {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
@@ -27,4 +27,73 @@
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tp__proxy-type-input {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: var(--gap-default);
|
||||
.tp__chip {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border-color: var(--active-color);
|
||||
}
|
||||
}
|
||||
|
||||
&__reverse.active,
|
||||
&__reverse-live.active,
|
||||
&__reverse-vod.active,
|
||||
&__reverse-series.active {
|
||||
color: var(--tag-active-color);
|
||||
background-color: var(--tag-active-background-color);
|
||||
border-color: var(--tag-active-border-color);
|
||||
}
|
||||
|
||||
&__reverse-live.redirect-active,
|
||||
&__reverse-vod.redirect-active,
|
||||
&__reverse-series.redirect-active,
|
||||
&__redirect.active {
|
||||
color: var(--tag-alt-active-color);
|
||||
background-color: var(--tag-alt-active-background-color);
|
||||
border-color: var(--tag-alt-active-border-color);
|
||||
}
|
||||
|
||||
&__mixed {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
span:not(:first-child) {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
span:not(:last-child) {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tp__chip__group {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
gap: var(--gap-default);
|
||||
}
|
||||
|
||||
// &__sub {
|
||||
// display: flex;
|
||||
// flex-flow: row nowrap;
|
||||
// span:not(:first-child) {
|
||||
// border-top-left-radius: 0;
|
||||
// border-bottom-left-radius: 0;
|
||||
// }
|
||||
// span:not(:last-child) {
|
||||
// border-top-right-radius: 0;
|
||||
// border-bottom-right-radius: 0;
|
||||
// }
|
||||
//
|
||||
// .tp__chip.active {
|
||||
// background-color: var(--tag-active-background-color);
|
||||
// color: var(--tag-active-color);
|
||||
// fill: var(--tag-active-color);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -2,9 +2,9 @@
|
||||
macro_rules! config_field_optional {
|
||||
($config:expr, $label:expr, $field:ident) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
<span class="tp__config-field__value">
|
||||
<span class="tp__form-field__value">
|
||||
{
|
||||
match $config.$field.as_ref() {
|
||||
Some(value) => html! { &value },
|
||||
@@ -21,9 +21,9 @@ macro_rules! config_field_optional {
|
||||
macro_rules! config_field_optional_hide {
|
||||
($config:expr, $label:expr, $field:ident) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
<span class="tp__config-field__value">
|
||||
<span class="tp__form-field__value">
|
||||
<$crate::app::components::HideContent content={$config.$field.as_ref().map_or_else(String::new, |content| content.clone())}></$crate::app::components::HideContent>
|
||||
</span>
|
||||
</div>
|
||||
@@ -35,9 +35,9 @@ macro_rules! config_field_optional_hide {
|
||||
macro_rules! config_field_hide {
|
||||
($config:expr, $label:expr, $field:ident) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
<span class="tp__config-field__value">
|
||||
<span class="tp__form-field__value">
|
||||
<$crate::app::components::HideContent content={$config.$field.clone()}></$crate::app::components::HideContent>
|
||||
</span>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@ macro_rules! config_field_hide {
|
||||
macro_rules! config_field_bool {
|
||||
($config:expr, $label:expr, $field:ident) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__bool">
|
||||
<div class="tp__form-field tp__form-field__bool">
|
||||
<label>{$label}</label>
|
||||
<$crate::app::components::ToggleSwitch value={$config.$field} readonly={true} />
|
||||
</div>
|
||||
@@ -61,7 +61,7 @@ macro_rules! config_field_bool {
|
||||
macro_rules! config_field_bool_empty {
|
||||
($label:expr) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__bool">
|
||||
<div class="tp__form-field tp__form-field__bool">
|
||||
<label>{$label}</label>
|
||||
<$crate::app::components::ToggleSwitch value={false} readonly={true} />
|
||||
</div>
|
||||
@@ -73,9 +73,9 @@ macro_rules! config_field_bool_empty {
|
||||
macro_rules! config_field {
|
||||
($config:expr, $label:expr, $field:ident) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
<span class="tp__config-field__value">{$config.$field.to_string()}</span>
|
||||
<span class="tp__form-field__value">{$config.$field.to_string()}</span>
|
||||
</div>
|
||||
}
|
||||
};
|
||||
@@ -85,7 +85,7 @@ macro_rules! config_field {
|
||||
macro_rules! config_field_child {
|
||||
($label:expr, $body:block) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
{ $body }
|
||||
</div>
|
||||
@@ -97,9 +97,9 @@ macro_rules! config_field_child {
|
||||
macro_rules! config_field_empty {
|
||||
($label:expr) => {
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<label>{$label}</label>
|
||||
<span class="tp__config-field__value"></span>
|
||||
<span class="tp__form-field__value"></span>
|
||||
</div>
|
||||
}
|
||||
};
|
||||
@@ -116,7 +116,7 @@ macro_rules! edit_field_text_option {
|
||||
(@inner $instance:expr, $label:expr, $field:ident, $hidden:expr) => {{
|
||||
let instance = $instance.clone();
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<$crate::app::components::input::Input
|
||||
label={$label}
|
||||
hidden={$hidden}
|
||||
@@ -147,7 +147,7 @@ macro_rules! edit_field_text {
|
||||
(@inner $instance:expr, $label:expr, $field:ident, $hidden:expr) => {{
|
||||
let instance = $instance.clone();
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__text">
|
||||
<div class="tp__form-field tp__form-field__text">
|
||||
<$crate::app::components::input::Input
|
||||
label={$label}
|
||||
hidden={$hidden}
|
||||
@@ -170,7 +170,7 @@ macro_rules! edit_field_bool {
|
||||
($instance:expr, $label:expr, $field:ident) => {{
|
||||
let instance = $instance.clone();
|
||||
html! {
|
||||
<div class="tp__config-field tp__config-field__bool">
|
||||
<div class="tp__form-field tp__form-field__bool">
|
||||
<label>{$label}</label>
|
||||
<$crate::app::components::ToggleSwitch
|
||||
value={instance.borrow().$field}
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::{
|
||||
};
|
||||
use yew::prelude::*;
|
||||
use yew_i18n::use_translation;
|
||||
use shared::model::WebUiConfigDto;
|
||||
|
||||
const LABEL_AUTH: &str = "LABEL.AUTH";
|
||||
const LABEL_ENABLED: &str = "LABEL.ENABLED";
|
||||
@@ -37,26 +38,75 @@ pub fn WebUiConfigView() -> Html {
|
||||
}
|
||||
};
|
||||
|
||||
let render_empty_csp = || {
|
||||
html! {
|
||||
<Card>
|
||||
<h1>{translate.t(LABEL_CONTENT_SECURITY_POLICY)}</h1>
|
||||
{ config_field_bool_empty!(translate.t(LABEL_ENABLED)) }
|
||||
{ config_field_empty!(translate.t(LABEL_CONTENT_SECURITY_POLICY_CUSTOM_ATTRIBUTES)) }
|
||||
</Card>
|
||||
}
|
||||
};
|
||||
|
||||
let render_empty = || {
|
||||
html! {
|
||||
<>
|
||||
{ config_field_bool_empty!(translate.t(LABEL_ENABLED)) }
|
||||
{ config_field_bool_empty!(translate.t(LABEL_USER_UI_ENABLED)) }
|
||||
{ config_field_child!(translate.t(LABEL_CONTENT_SECURITY_POLICY), {
|
||||
html! {
|
||||
<>
|
||||
{ config_field_bool_empty!(translate.t(LABEL_ENABLED)) }
|
||||
{ config_field_empty!(translate.t(LABEL_CONTENT_SECURITY_POLICY_CUSTOM_ATTRIBUTES)) }
|
||||
</>
|
||||
}
|
||||
}) }
|
||||
{ config_field_empty!(translate.t(LABEL_PATH)) }
|
||||
{ config_field_empty!(translate.t(LABEL_PLAYER_SERVER)) }
|
||||
{ render_empty_csp()}
|
||||
{ render_empty_auth() }
|
||||
</>
|
||||
}
|
||||
};
|
||||
|
||||
let render_csp = |web_ui: &WebUiConfigDto| {
|
||||
html! {
|
||||
{
|
||||
match web_ui.content_security_policy.as_ref() {
|
||||
Some(csp) => html! {
|
||||
<Card>
|
||||
<h1>{translate.t(LABEL_CONTENT_SECURITY_POLICY)}</h1>
|
||||
{ config_field_bool!(csp, translate.t(LABEL_ENABLED), enabled) }
|
||||
{ config_field_child!(translate.t(LABEL_CONTENT_SECURITY_POLICY_CUSTOM_ATTRIBUTES), {
|
||||
html! {
|
||||
<div class="tp__config-view__tags">
|
||||
{
|
||||
if let Some(custom) = &csp.custom_attributes {
|
||||
html! { for custom.iter().map(|a| html! { <Chip label={a.clone()} /> }) }
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}) }
|
||||
</Card>
|
||||
},
|
||||
None => render_empty_csp()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let render_auth = |web_ui: &WebUiConfigDto| html! {
|
||||
{
|
||||
match web_ui.auth.as_ref() {
|
||||
Some(auth) => html!{
|
||||
<Card>
|
||||
<h1>{translate.t(LABEL_AUTH)}</h1>
|
||||
{ config_field_bool!(auth, translate.t(LABEL_ENABLED), enabled) }
|
||||
{ config_field!(auth, translate.t(LABEL_ISSUER), issuer) }
|
||||
{ config_field_hide!(auth, translate.t(LABEL_SECRET), secret) }
|
||||
{ config_field!(auth, translate.t(LABEL_TOKEN_TTL_MINS), token_ttl_mins) }
|
||||
{ config_field_optional!(auth, translate.t(LABEL_USERFILE), userfile) }
|
||||
</Card>
|
||||
},
|
||||
None => render_empty_auth(),
|
||||
}}
|
||||
};
|
||||
|
||||
html! {
|
||||
<div class="tp__webui-config-view tp__config-view-page">
|
||||
<div class="tp__webui-config-config-view__body tp__config-view-page__body">
|
||||
@@ -67,54 +117,10 @@ pub fn WebUiConfigView() -> Html {
|
||||
<>
|
||||
{ config_field_bool!(web_ui, translate.t(LABEL_ENABLED), enabled) }
|
||||
{ config_field_bool!(web_ui, translate.t(LABEL_USER_UI_ENABLED), user_ui_enabled) }
|
||||
{ config_field_child!(translate.t(LABEL_CONTENT_SECURITY_POLICY), {
|
||||
html! {
|
||||
match web_ui.content_security_policy.as_ref() {
|
||||
Some(csp) => html! {
|
||||
<>
|
||||
{ config_field_bool!(csp, translate.t(LABEL_ENABLED), enabled) }
|
||||
{ config_field_child!(translate.t(LABEL_CONTENT_SECURITY_POLICY_CUSTOM_ATTRIBUTES), {
|
||||
html! {
|
||||
<div class="tp__config-view__tags">
|
||||
{
|
||||
if let Some(custom) = &csp.custom_attributes {
|
||||
html! { for custom.iter().map(|a| html! { <Chip label={a.clone()} /> }) }
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}) }
|
||||
</>
|
||||
},
|
||||
None => html! {
|
||||
<>
|
||||
{ config_field_bool_empty!(translate.t(LABEL_ENABLED)) }
|
||||
{ config_field_empty!(translate.t(LABEL_CONTENT_SECURITY_POLICY_CUSTOM_ATTRIBUTES)) }
|
||||
</>
|
||||
}
|
||||
}
|
||||
}
|
||||
}) }
|
||||
{ config_field_optional!(web_ui, translate.t(LABEL_PATH), path) }
|
||||
{ config_field_optional!(web_ui, translate.t(LABEL_PLAYER_SERVER), player_server) }
|
||||
<Card>
|
||||
<h1>{translate.t(LABEL_AUTH)}</h1>
|
||||
{
|
||||
match web_ui.auth.as_ref() {
|
||||
Some(auth) => html!{
|
||||
<>
|
||||
{ config_field_bool!(auth, translate.t(LABEL_ENABLED), enabled) }
|
||||
{ config_field!(auth, translate.t(LABEL_ISSUER), issuer) }
|
||||
{ config_field_hide!(auth, translate.t(LABEL_SECRET), secret) }
|
||||
{ config_field!(auth, translate.t(LABEL_TOKEN_TTL_MINS), token_ttl_mins) }
|
||||
{ config_field_optional!(auth, translate.t(LABEL_USERFILE), userfile) }
|
||||
</>
|
||||
},
|
||||
None => render_empty_auth(),
|
||||
}}
|
||||
</Card>
|
||||
{ render_csp(web_ui) }
|
||||
{ render_auth(web_ui) }
|
||||
</>
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,69 +1,141 @@
|
||||
use shared::model::{ProxyType};
|
||||
use shared::model::{ClusterFlags, ProxyType};
|
||||
use yew::prelude::*;
|
||||
use yew_i18n::use_translation;
|
||||
|
||||
fn get_flags(pt: ProxyType)-> (bool, bool, bool, bool, bool) {
|
||||
match pt {
|
||||
ProxyType::Reverse(flags) => {
|
||||
let cluster = flags.unwrap_or_else(ClusterFlags::all);
|
||||
let live_flag = cluster.contains(ClusterFlags::Live);
|
||||
let vod_flag = cluster.contains(ClusterFlags::Vod);
|
||||
let series_flag = cluster.contains(ClusterFlags::Series);
|
||||
(false, true, live_flag, vod_flag, series_flag)
|
||||
}
|
||||
ProxyType::Redirect => (true, false, false, false, false),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Properties, Clone, PartialEq, Debug)]
|
||||
pub struct ProxyTypeInputProps {
|
||||
pub value: ProxyType,
|
||||
#[prop_or_default]
|
||||
pub onchange: Callback<ProxyType>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn ProxyTypeInput(props: &ProxyTypeInputProps) -> Html {
|
||||
let translate = use_translation();
|
||||
//
|
||||
// let render_chip = |flag: bool, class_sfx: &str, label: &str, | -> Html {
|
||||
// if flag {
|
||||
// html! {
|
||||
// <Chip class={ format!("tp__proxy-type__reverse tp__proxy-type__reverse-{} active", class_sfx) } label={translate.t(label)} />
|
||||
// }
|
||||
// } else {
|
||||
// html!{
|
||||
// <Chip class={ format!("tp__proxy-type__redirect tp__proxy-type__redirect-{}", class_sfx)} label={translate.t(label)} />
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// match props.value {
|
||||
// ProxyType::Reverse(flags) => {
|
||||
// let cluster = flags.unwrap_or_else(ClusterFlags::all);
|
||||
// let live_flag = cluster.contains(ClusterFlags::Live);
|
||||
// let vod_flag = cluster.contains(ClusterFlags::Vod);
|
||||
// let series_flag = cluster.contains(ClusterFlags::Series);
|
||||
// if live_flag && vod_flag && series_flag {
|
||||
// html! { <Chip label={translate.t("LABEL.REVERSE")} class={"tp__proxy-type__reverse"} /> }
|
||||
// } else {
|
||||
// html! {
|
||||
// <div class="tp__proxy-type__mixed">
|
||||
// { render_chip(live_flag, "live", "LABEL.LIVE_SHORT") }
|
||||
// { render_chip(vod_flag, "vod", "LABEL.VOD_SHORT") }
|
||||
// { render_chip(series_flag, "series", "LABEL.SERIES_SHORT" ) }
|
||||
// </div>
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ProxyType::Redirect => html! {
|
||||
// <Chip label={translate.t("LABEL.REDIRECT")} class={"tp__proxy-type__redirect"} />
|
||||
// },
|
||||
// }
|
||||
let selections = use_state(|| get_flags(props.value));
|
||||
|
||||
let handle_redirect_click = {
|
||||
Callback::from(move |_| {
|
||||
println!("redirect");
|
||||
{
|
||||
let set_selections = selections.clone();
|
||||
use_effect_with(props.value, move |pt| {
|
||||
set_selections.set(get_flags(*pt));
|
||||
});
|
||||
}
|
||||
|
||||
let handle_change = {
|
||||
let onchange = props.onchange.clone();
|
||||
Callback::from(move |(redirect, _reverse, live, vod, series)| {
|
||||
if redirect {
|
||||
onchange.emit(ProxyType::Redirect);
|
||||
} else {
|
||||
let cluster_flags = if live && vod && series {
|
||||
None
|
||||
} else {
|
||||
let mut flags = ClusterFlags::empty();
|
||||
if live {
|
||||
flags.insert(ClusterFlags::Live);
|
||||
}
|
||||
if vod {
|
||||
flags.insert(ClusterFlags::Vod);
|
||||
}
|
||||
if series {
|
||||
flags.insert(ClusterFlags::Series);
|
||||
}
|
||||
Some(flags)
|
||||
};
|
||||
onchange.emit(ProxyType::Reverse(cluster_flags));
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let handle_redirect_click = {
|
||||
let set_selections = selections.clone();
|
||||
let emit_change = handle_change.clone();
|
||||
Callback::from(move |_| {
|
||||
let new_flags = (true, false, false, false, false);
|
||||
set_selections.set(new_flags);
|
||||
emit_change.emit(new_flags);
|
||||
})
|
||||
};
|
||||
let handle_reverse_click = {
|
||||
let set_selections = selections.clone();
|
||||
let emit_change = handle_change.clone();
|
||||
Callback::from(move |_| {
|
||||
let new_flags = (false, true, true, true, true);
|
||||
set_selections.set(new_flags);
|
||||
emit_change.emit(new_flags);
|
||||
})
|
||||
};
|
||||
let handle_reverse_live_click = {
|
||||
let set_selections = selections.clone();
|
||||
let emit_change = handle_change.clone();
|
||||
Callback::from(move |_| {
|
||||
let flags = *set_selections;
|
||||
let new_flags = if flags.0 {
|
||||
(false, true, true, true, true)
|
||||
} else {
|
||||
(false, true, !flags.2, flags.3, flags.4)
|
||||
};
|
||||
set_selections.set(new_flags);
|
||||
emit_change.emit(new_flags);
|
||||
})
|
||||
};
|
||||
let handle_reverse_vod_click = {
|
||||
let set_selections = selections.clone();
|
||||
let emit_change = handle_change.clone();
|
||||
Callback::from(move |_| {
|
||||
let flags = *set_selections;
|
||||
let new_flags = if flags.0 {
|
||||
(false, true, true, true, true)
|
||||
} else {
|
||||
(false, true, flags.2, !flags.3, flags.4)
|
||||
};
|
||||
set_selections.set(new_flags);
|
||||
emit_change.emit(new_flags);
|
||||
})
|
||||
};
|
||||
|
||||
let handle_reverse_series_click = {
|
||||
let set_selections = selections.clone();
|
||||
let emit_change = handle_change.clone();
|
||||
Callback::from(move |_| {
|
||||
let flags = *set_selections;
|
||||
let new_flags = if flags.0 {
|
||||
(false, true, true, true, true)
|
||||
} else {
|
||||
(false, true, flags.2, flags.3, !flags.4)
|
||||
};
|
||||
set_selections.set(new_flags);
|
||||
emit_change.emit(new_flags);
|
||||
})
|
||||
};
|
||||
|
||||
let (redirect, reverse, reverse_live, reverse_vod, reverse_series) = *selections;
|
||||
|
||||
html! {
|
||||
<div class="tp__proxy-type-input">
|
||||
<span class={"tp__chip"} onclick={handle_redirect_click}>
|
||||
<span class="tp__chip__label">{ translate.t("LABEL.REDIRECT") }</span>
|
||||
<span onclick={handle_redirect_click} class={classes!("tp__chip", "tp__proxy-type-input__redirect", if redirect {"active"} else {""})}>
|
||||
<span>{ translate.t("LABEL.REDIRECT") }</span>
|
||||
</span>
|
||||
|
||||
<span class={"tp__chip"}>
|
||||
<span class="tp__chip__label">{ translate.t("LABEL.REVERSE") }</span>
|
||||
<span class={"tp__chip__group"}>
|
||||
<span class="tp__chip__label">{ translate.t("LABEL.LIVE") }</span>
|
||||
<span class="tp__chip__label">{ translate.t("LABEL.VIDEO") }</span>
|
||||
<span class="tp__chip__label">{ translate.t("LABEL.SERIES") }</span>
|
||||
<span class={classes!("tp__chip", "tp__chip__group", "tp__proxy-type-input__reverse" , if reverse {"active"} else {""})}>
|
||||
<span onclick={handle_reverse_click}>{ translate.t("LABEL.REVERSE") }</span>
|
||||
<span class={"tp__chip__group__sub tp__proxy-type-input__mixed"}>
|
||||
<span onclick={handle_reverse_live_click} class={classes!("tp__chip", "tp__proxy-type-input__reverse-live", if reverse_live {"active"} else { if reverse {"redirect-active"} else {""} })}>{ translate.t("LABEL.LIVE_SHORT") }</span>
|
||||
<span onclick={handle_reverse_vod_click} class={classes!("tp__chip", "tp__proxy-type-input__reverse-vod", if reverse_vod {"active"} else {if reverse {"redirect-active"} else {""} })}>{ translate.t("LABEL.VOD_SHORT") }</span>
|
||||
<span onclick={handle_reverse_series_click} class={classes!("tp__chip", "tp__proxy-type-input__reverse-series", if reverse_series {"active"} else {if reverse {"redirect-active"} else {""} })}>{ translate.t("LABEL.SERIES_SHORT") }</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -89,8 +89,12 @@ pub fn ProxyUserCredentialsForm(props: &ProxyUserCredentialsFormProps) -> Html {
|
||||
|
||||
{ config_field_child!(translate.t("LABEL.PROXY"), {
|
||||
html! {
|
||||
<ProxyTypeInput value={props.user.as_ref().map_or_else(|| ProxyType::Reverse(None), |u| u.credentials.proxy)} />
|
||||
<ProxyTypeInput value={props.user.as_ref().map_or_else(|| ProxyType::Reverse(None), |u| u.credentials.proxy)}
|
||||
onchange={Callback::from(|proxy_type: ProxyType|
|
||||
warn!("Proxy Type: {:?}", proxy_type)
|
||||
)}/>
|
||||
}})}
|
||||
|
||||
<label>{ translate.t("LABEL.PROXY") }</label>
|
||||
<span>{"TODO"}</span>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user