mirror of
https://github.com/mii443/vrclipboard-ime-gui.git
synced 2025-08-22 16:15:32 +00:00
add auto skip when outside of VRChat
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "vrclipboard-ime-gui",
|
"name": "vrclipboard-ime-gui",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.8.0",
|
"version": "1.9.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"url": "https://r2-vrime.mii.dev/releases/vrclipboard-ime-gui_1.8.0_x64_ja-JP.msi.zip",
|
"url": "https://r2-vrime.mii.dev/releases/vrclipboard-ime-gui_1.9.0_x64_ja-JP.msi.zip",
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"notes": "ログの出力を改善",
|
"notes": "ログの出力を改善",
|
||||||
"pub_date": "2024-09-25T14:51:05+00:00",
|
"pub_date": "2024-09-25T14:51:05+00:00",
|
||||||
|
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@ -3903,7 +3903,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vrclipboard-ime-gui"
|
name = "vrclipboard-ime-gui"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"calc",
|
"calc",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vrclipboard-ime-gui"
|
name = "vrclipboard-ime-gui"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
description = "VRClipboard IME"
|
description = "VRClipboard IME"
|
||||||
authors = ["mii"]
|
authors = ["mii"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@ -41,6 +41,7 @@ features = [
|
|||||||
"Win32_UI_Input_Ime",
|
"Win32_UI_Input_Ime",
|
||||||
"Win32_UI_TextServices",
|
"Win32_UI_TextServices",
|
||||||
"Win32_UI_Input_KeyboardAndMouse",
|
"Win32_UI_Input_KeyboardAndMouse",
|
||||||
|
"Win32_System_DataExchange",
|
||||||
"Win32_UI_WindowsAndMessaging"
|
"Win32_UI_WindowsAndMessaging"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -24,7 +24,9 @@ pub struct Config {
|
|||||||
#[serde(default = "bool_true")]
|
#[serde(default = "bool_true")]
|
||||||
pub skip_url: bool,
|
pub skip_url: bool,
|
||||||
#[serde(default = "bool_false")]
|
#[serde(default = "bool_false")]
|
||||||
pub use_tsf_reconvert: bool
|
pub use_tsf_reconvert: bool,
|
||||||
|
#[serde(default = "bool_true")]
|
||||||
|
pub skip_on_out_of_vrc: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -36,7 +38,8 @@ impl Default for Config {
|
|||||||
ignore_prefix: true,
|
ignore_prefix: true,
|
||||||
on_copy_mode: OnCopyMode::ReturnToChatbox,
|
on_copy_mode: OnCopyMode::ReturnToChatbox,
|
||||||
skip_url: true,
|
skip_url: true,
|
||||||
use_tsf_reconvert: false
|
use_tsf_reconvert: false,
|
||||||
|
skip_on_out_of_vrc: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use clipboard_master::{ClipboardHandler, CallbackResult};
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rosc::{encoder, OscMessage, OscPacket, OscType};
|
use rosc::{encoder, OscMessage, OscPacket, OscType};
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager};
|
||||||
|
use windows::Win32::System::DataExchange::GetClipboardOwner;
|
||||||
use crate::{config::{Config, OnCopyMode}, conversion::Conversion, tsf_conversion::TsfConversion, Log, STATE};
|
use crate::{config::{Config, OnCopyMode}, conversion::Conversion, tsf_conversion::TsfConversion, Log, STATE};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use tracing::{info, warn, error};
|
use tracing::{info, warn, error};
|
||||||
@ -34,6 +35,10 @@ impl ConversionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ConversionHandler {
|
impl ConversionHandler {
|
||||||
|
fn clipboard_has_owner(&mut self) -> bool {
|
||||||
|
unsafe { GetClipboardOwner() }.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
fn tsf_conversion(&mut self, contents: &str, config: &Config) -> Result<()> {
|
fn tsf_conversion(&mut self, contents: &str, config: &Config) -> Result<()> {
|
||||||
if contents.chars().count() > 140 {
|
if contents.chars().count() > 140 {
|
||||||
info!("Content exceeds 140 characters, skipping TSF conversion");
|
info!("Content exceeds 140 characters, skipping TSF conversion");
|
||||||
@ -126,6 +131,11 @@ impl ConversionHandler {
|
|||||||
impl ClipboardHandler for ConversionHandler {
|
impl ClipboardHandler for ConversionHandler {
|
||||||
fn on_clipboard_change(&mut self) -> CallbackResult {
|
fn on_clipboard_change(&mut self) -> CallbackResult {
|
||||||
let config = self.get_config();
|
let config = self.get_config();
|
||||||
|
if config.skip_on_out_of_vrc && self.clipboard_has_owner() {
|
||||||
|
info!("Clipboard has owner (maybe from outside of VRChat), skipping conversion");
|
||||||
|
return CallbackResult::Next;
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(mut contents) = self.clipboard_ctx.get_contents() {
|
if let Ok(mut contents) = self.clipboard_ctx.get_contents() {
|
||||||
if config.use_tsf_reconvert {
|
if config.use_tsf_reconvert {
|
||||||
if let Err(e) = self.tsf_conversion(&contents, &config) {
|
if let Err(e) = self.tsf_conversion(&contents, &config) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "vrclipboard-ime-gui",
|
"productName": "vrclipboard-ime-gui",
|
||||||
"version": "1.8.0"
|
"version": "1.9.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"updater": {
|
"updater": {
|
||||||
|
@ -10,6 +10,7 @@ interface Config {
|
|||||||
on_copy_mode: OnCopyMode;
|
on_copy_mode: OnCopyMode;
|
||||||
skip_url: boolean;
|
skip_url: boolean;
|
||||||
use_tsf_reconvert: boolean;
|
use_tsf_reconvert: boolean;
|
||||||
|
skip_on_out_of_vrc: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OnCopyMode {
|
enum OnCopyMode {
|
||||||
@ -26,7 +27,8 @@ const SettingsComponent = () => {
|
|||||||
ignore_prefix: false,
|
ignore_prefix: false,
|
||||||
on_copy_mode: OnCopyMode.ReturnToChatbox,
|
on_copy_mode: OnCopyMode.ReturnToChatbox,
|
||||||
skip_url: true,
|
skip_url: true,
|
||||||
use_tsf_reconvert: false
|
use_tsf_reconvert: false,
|
||||||
|
skip_on_out_of_vrc: true,
|
||||||
});
|
});
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||||
@ -48,9 +50,9 @@ const SettingsComponent = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveSettings = async () => {
|
const saveSettings = async (newSettings: Config) => {
|
||||||
try {
|
try {
|
||||||
await invoke('save_settings', { config: settings });
|
await invoke('save_settings', { config: newSettings });
|
||||||
alert('設定が正常に保存されました。');
|
alert('設定が正常に保存されました。');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to save settings:', error);
|
console.error('Failed to save settings:', error);
|
||||||
@ -60,15 +62,19 @@ const SettingsComponent = () => {
|
|||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value, type, checked } = e.target;
|
const { name, value, type, checked } = e.target;
|
||||||
setSettings(prev => ({
|
const newSettings = {
|
||||||
...prev,
|
...settings,
|
||||||
[name]: type === 'checkbox' ? checked : value
|
[name]: type === 'checkbox' ? checked : value
|
||||||
}));
|
};
|
||||||
|
setSettings(newSettings);
|
||||||
|
saveSettings(newSettings);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectChange = (value: OnCopyMode) => {
|
const handleSelectChange = (value: OnCopyMode) => {
|
||||||
setSettings(prev => ({ ...prev, on_copy_mode: value }));
|
const newSettings = { ...settings, on_copy_mode: value };
|
||||||
|
setSettings(newSettings);
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
|
saveSettings(newSettings);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
@ -195,12 +201,19 @@ const SettingsComponent = () => {
|
|||||||
Windows10または11を使用している場合は、「以前のバージョンの Microsoft IME を使う」を有効化する必要があります。
|
Windows10または11を使用している場合は、「以前のバージョンの Microsoft IME を使う」を有効化する必要があります。
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex items-center">
|
||||||
onClick={saveSettings}
|
<input
|
||||||
className="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition-colors"
|
type="checkbox"
|
||||||
>
|
id="skip_on_out_of_vrc"
|
||||||
保存
|
name="skip_on_out_of_vrc"
|
||||||
</button>
|
checked={settings.skip_on_out_of_vrc}
|
||||||
|
onChange={handleChange}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
<label htmlFor="skip_on_out_of_vrc" className="text-sm font-medium text-gray-700">
|
||||||
|
VRChat以外からのコピーをスキップ
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,7 @@ const TitleBar = () => {
|
|||||||
<div className="flex justify-between items-center bg-gray-800 text-white h-8 px-2" data-tauri-drag-region>
|
<div className="flex justify-between items-center bg-gray-800 text-white h-8 px-2" data-tauri-drag-region>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<span className="text-sm font-semibold">VRClipboard-IME</span>
|
<span className="text-sm font-semibold">VRClipboard-IME</span>
|
||||||
<span className="text-xs font-semibold ml-2">v1.7.0</span>
|
<span className="text-xs font-semibold ml-2">v1.9.0</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<button onClick={handleMinimize} className="p-1 hover:bg-gray-700 focus:outline-none">
|
<button onClick={handleMinimize} className="p-1 hover:bg-gray-700 focus:outline-none">
|
||||||
|
Reference in New Issue
Block a user