Some more changes for 1.4.9
This commit is contained in:
		
							parent
							
								
									598b1dd493
								
							
						
					
					
						commit
						93b4521673
					
				
							
								
								
									
										2
									
								
								github
									
									
									
									
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								github
									
									
									
									
									
								
							| @ -1 +1 @@ | ||||
| Subproject commit 605c418ac7e5b158426cee96712e7bbc2033e0b6 | ||||
| Subproject commit 2d7be74482f4bec8f06810b3cd8406785ebfcfa1 | ||||
| @ -22,7 +22,7 @@ class ExternalModalController extends AbstractExternalModalController { | ||||
|         } | ||||
| 
 | ||||
|         this.window = new remote.BrowserWindow({ | ||||
|             parent: remote.getCurrentWindow(), | ||||
|             /* parent: remote.getCurrentWindow(), */ /* do not link them together */ | ||||
|             autoHideMenuBar: true, | ||||
| 
 | ||||
|             webPreferences: { | ||||
|  | ||||
| @ -1,35 +1,26 @@ | ||||
| import * as electron from "electron"; | ||||
| import * as loader from "tc-loader"; | ||||
| import {Stage} from "tc-loader"; | ||||
| import NativeImage = electron.NativeImage; | ||||
| 
 | ||||
| let _div: JQuery; | ||||
| let _icon_mash_url: string; | ||||
| let _icon_mask_img: NativeImage; | ||||
| let _cache_klass_map: {[key: string]: NativeImage}; | ||||
| import { | ||||
|     spriteUrl as kClientSpriteUrl, | ||||
|     spriteWidth as kClientSpriteWidth, | ||||
|     spriteHeight as kClientSpriteHeight, | ||||
|     spriteEntries as kClientSpriteEntries | ||||
| } from "svg-sprites/client-icons"; | ||||
| import {NativeImage} from "electron"; | ||||
| 
 | ||||
| export function class_to_image(klass: string) : NativeImage { | ||||
|     if(!klass || !_icon_mask_img || !_cache_klass_map) | ||||
|         return undefined; | ||||
| let nativeSprite: NativeImage; | ||||
| 
 | ||||
|     if(_cache_klass_map[klass]) | ||||
|         return _cache_klass_map[klass]; | ||||
| export function clientIconClassToImage(klass: string) : NativeImage { | ||||
|     const sprite = kClientSpriteEntries.find(e => e.className === klass); | ||||
|     if(!sprite) return undefined; | ||||
| 
 | ||||
|     _div[0].classList.value = 'icon ' + klass; | ||||
|     const data = window.getComputedStyle(_div[0]); | ||||
| 
 | ||||
|     const offset_x = parseInt(data.backgroundPositionX.split(",")[0]); | ||||
|     const offset_y = parseInt(data.backgroundPositionY.split(",")[0]); | ||||
| 
 | ||||
|     //http://localhost/home/TeaSpeak/Web-Client/web/environment/development/img/client_icon_sprite.svg
 | ||||
|     //const hight = element.css('height');
 | ||||
|     //const width = element.css('width');
 | ||||
|     console.log("Offset: x: %o y: %o;", offset_x, offset_y); | ||||
|     return _cache_klass_map[klass] = _icon_mask_img.crop({ | ||||
|         height: 16, | ||||
|         width: 16, | ||||
|         x: offset_x == 0 ? 0 : -offset_x, | ||||
|         y: offset_y == 0 ? 0 : -offset_y | ||||
|     return nativeSprite.crop({ | ||||
|         height: sprite.height, | ||||
|         width: sprite.width, | ||||
|         x: sprite.xOffset, | ||||
|         y: sprite.yOffset | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| @ -37,33 +28,22 @@ loader.register_task(Stage.JAVASCRIPT_INITIALIZING, { | ||||
|     priority: 100, | ||||
|     name: "native icon sprite loader", | ||||
|     function: async () => { | ||||
|         if(!_div) { | ||||
|             _div = $(document.createElement("div")); | ||||
|             _div.css('display', 'none'); | ||||
|             _div.appendTo(document.body); | ||||
|         } | ||||
| 
 | ||||
|         const image = new Image(); | ||||
|         image.src = 'img/client_icon_sprite.svg'; | ||||
|         image.src = kClientSpriteUrl; | ||||
|         await new Promise((resolve, reject) => { | ||||
|             image.onload = resolve; | ||||
|             image.onerror = reject; | ||||
|             image.onerror = () => reject("failed to load client icon sprite"); | ||||
|         }); | ||||
| 
 | ||||
|         /* TODO: Get a size! */ | ||||
|         const canvas = document.createElement("canvas"); | ||||
|         canvas.width = 1024; | ||||
|         canvas.height = 1024; | ||||
|         canvas.width = kClientSpriteWidth; | ||||
|         canvas.height = kClientSpriteHeight; | ||||
|         canvas.getContext("2d").drawImage(image, 0, 0); | ||||
| 
 | ||||
|         _cache_klass_map = {}; | ||||
|         _icon_mash_url = canvas.toDataURL(); | ||||
|         _icon_mask_img = electron.remote.nativeImage.createFromDataURL(_icon_mash_url); | ||||
|         nativeSprite = electron.remote.nativeImage.createFromDataURL( canvas.toDataURL()); | ||||
|     } | ||||
| }) | ||||
| 
 | ||||
| export function finalize() { | ||||
|     _icon_mask_img = undefined; | ||||
|     _icon_mash_url = undefined; | ||||
|     _cache_klass_map = undefined; | ||||
|     nativeSprite = undefined; | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| import {class_to_image} from "./IconHelper"; | ||||
| import {clientIconClassToImage} from "./IconHelper"; | ||||
| import * as electron from "electron"; | ||||
| import * as mbar from "tc-shared/ui/frames/MenuBar"; | ||||
| import {Arguments, process_args} from "../shared/process-arguments"; | ||||
| @ -73,7 +73,7 @@ namespace native { | ||||
| 
 | ||||
|         icon(klass?: string | Promise<LocalIcon> | LocalIcon): string { | ||||
|             if(typeof(klass) === "string") { | ||||
|                 const buffer = class_to_image(klass); | ||||
|                 const buffer = clientIconClassToImage(klass); | ||||
|                 if(buffer) | ||||
|                     this._icon_data = buffer.toDataURL(); | ||||
|             } | ||||
|  | ||||
| @ -60,7 +60,6 @@ export async function initialize() { | ||||
|         }); | ||||
|         (_new_storage as any)["length"] = Object.keys(_local_storage).length; | ||||
|     }; | ||||
| 
 | ||||
|     Object.assign(window.localStorage, _new_storage); | ||||
| 
 | ||||
|     /* try to save everything all 60 seconds */ | ||||
| @ -93,6 +92,7 @@ export async function delete_key(key: string) { | ||||
|     await fs.remove(setting_path); /* could be async because we're not carrying about data */ | ||||
| } | ||||
| 
 | ||||
| window.addEventListener("beforeunload", event => { | ||||
| window.addEventListener("beforeunload", () => { | ||||
|     console.log("Save local storage"); | ||||
|     save_all_sync(); | ||||
| }); | ||||
| @ -94,6 +94,41 @@ overrides.push({ | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| function resolveModuleMapping(context: string, resource: string) { | ||||
|     if(context.endsWith("/")) | ||||
|         context = context.substring(0, context.length - 1); | ||||
| 
 | ||||
|     const loader = require("tc-loader"); | ||||
| 
 | ||||
|     const mapping = loader.module_mapping().find(e => e.application === "client-app"); //FIXME: Variable name!
 | ||||
|     if(!mapping) throw "missing mapping"; | ||||
| 
 | ||||
|     const entries = mapping.modules.filter(e => e.context === context); | ||||
|     if(!entries.length) { | ||||
|         debugger; | ||||
|         throw "unknown target path"; | ||||
|     } | ||||
| 
 | ||||
|     const entry = entries.find(e => path.basename(e.resource, path.extname(e.resource)) === resource); | ||||
|     if(!entry) { | ||||
|         if(resource.indexOf(".") === -1 && !resource.endsWith("/")) | ||||
|             return resolveModuleMapping(context + "/" + resource, "index"); | ||||
| 
 | ||||
|         throw "unknown import (" + context + "/" + resource + ")"; | ||||
|     } | ||||
| 
 | ||||
|     return entry.id; | ||||
| } | ||||
| 
 | ||||
| overrides.push({ | ||||
|     name: "svg sprites", | ||||
|     test: /^svg-sprites\/.*/, | ||||
|     callback: request => { | ||||
|         const entryId = resolveModuleMapping("svg-sprites", request.substring("svg-sprites/".length)); | ||||
|         return window["shared-require"](entryId); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| overrides.push({ | ||||
|     name: "shared loader", | ||||
|     test: /^tc-shared\/.*/, | ||||
| @ -101,25 +136,8 @@ overrides.push({ | ||||
|         if(request.endsWith("/")) | ||||
|             return require(request + "index"); | ||||
| 
 | ||||
|         const webpack_path = path.dirname("shared/js/" + request.substr(10)); //FIXME: Get the prefix from a variable!
 | ||||
|         const loader = require("tc-loader"); | ||||
| 
 | ||||
|         const mapping = loader.module_mapping().find(e => e.application === "client-app"); //FIXME: Variable name!
 | ||||
|         if(!mapping) throw "missing mapping"; | ||||
| 
 | ||||
|         const entries = mapping.modules.filter(e => e.context.startsWith(webpack_path)); | ||||
|         if(!entries.length) throw "unknown target path"; | ||||
| 
 | ||||
|         const basename = path.basename(request, path.extname(request)); | ||||
|         const entry = entries.find(e => path.basename(e.resource, path.extname(e.resource)) === basename); | ||||
|         if(!entry) { | ||||
|             if(basename.indexOf(".") === -1 && !request.endsWith("/")) | ||||
|                 return require(request + "/index"); | ||||
| 
 | ||||
|             debugger; | ||||
|             throw "unknown import (" + request + ")"; | ||||
|         } | ||||
| 
 | ||||
|         return window["shared-require"](entry.id); | ||||
|         let contextPath = path.dirname(request.substr(10)); | ||||
|         const entryId = resolveModuleMapping("shared/js/" + (contextPath === "." ? "" : contextPath), path.basename(request, path.extname(request))); | ||||
|         return window["shared-require"](entryId); | ||||
|     } | ||||
| }); | ||||
| @ -9,7 +9,7 @@ export async function play_sound(file: SoundFile) : Promise<void> { | ||||
|             pathname = pathname.substr(1); | ||||
|         const path = paths.join(pathname, file.path); | ||||
| 
 | ||||
|         console.log(path); | ||||
|         console.log("replaying %s (volume: %f)", file.path, file.volume); | ||||
|         naudio.sounds.playback_sound({ | ||||
|             callback: (result, message) => { | ||||
|                 if(result == naudio.sounds.PlaybackResult.SUCCEEDED) | ||||
| @ -18,7 +18,7 @@ export async function play_sound(file: SoundFile) : Promise<void> { | ||||
|                     reject(naudio.sounds.PlaybackResult[result].toLowerCase() + ": " + message); | ||||
|             }, | ||||
|             file: path, | ||||
|             volume: file.volume | ||||
|             volume: file.volume || 1 | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| import {class_to_image} from "./IconHelper"; | ||||
| import {clientIconClassToImage} from "./IconHelper"; | ||||
| import * as contextmenu from "tc-shared/ui/elements/ContextMenu"; | ||||
| import * as electron from "electron"; | ||||
| const remote = electron.remote; | ||||
| @ -56,7 +56,7 @@ class ElectronContextMenu implements contextmenu.ContextMenuProvider { | ||||
|                 label: (typeof entry.name === "function" ? (entry.name as (() => string))() : entry.name) as string, | ||||
|                 type: "normal", | ||||
|                 click: click_callback, | ||||
|                 icon: class_to_image(entry.icon_class), | ||||
|                 icon: clientIconClassToImage(entry.icon_class), | ||||
|                 visible: entry.visible, | ||||
|                 enabled: !entry.disabled | ||||
|             }); | ||||
| @ -77,7 +77,7 @@ class ElectronContextMenu implements contextmenu.ContextMenuProvider { | ||||
|                 type: "checkbox", | ||||
|                 checked: !!entry.checkbox_checked, | ||||
|                 click: click_callback, | ||||
|                 icon: class_to_image(entry.icon_class), | ||||
|                 icon: clientIconClassToImage(entry.icon_class), | ||||
|                 visible: entry.visible, | ||||
|                 enabled: !entry.disabled | ||||
|             }); | ||||
| @ -95,7 +95,7 @@ class ElectronContextMenu implements contextmenu.ContextMenuProvider { | ||||
|                 type: "submenu", | ||||
|                 submenu: sub_menu, | ||||
|                 click: click_callback, | ||||
|                 icon: class_to_image(entry.icon_class), | ||||
|                 icon: clientIconClassToImage(entry.icon_class), | ||||
|                 visible: entry.visible, | ||||
|                 enabled: !entry.disabled | ||||
|             }); | ||||
|  | ||||
| @ -10,7 +10,12 @@ else() | ||||
| endif() | ||||
| 
 | ||||
| add_nodejs_module(${MODULE_NAME} binding.cc ${SOURCE_FILES}) | ||||
| if (WIN32) | ||||
| 	target_compile_definitions(${MODULE_NAME} PUBLIC /O2) | ||||
| endif() | ||||
| 
 | ||||
| add_executable(Hook-Test ${SOURCE_FILES} test/HookTest.cpp) | ||||
| 
 | ||||
| if(NOT MSVC) | ||||
| 	target_link_libraries(${MODULE_NAME} X11) | ||||
| 	target_link_libraries(Hook-Test X11 pthread) | ||||
|  | ||||
| @ -173,6 +173,9 @@ endif() | ||||
| add_definitions(-DNO_OPEN_SSL) | ||||
| target_link_libraries(${MODULE_NAME} ${REQUIRED_LIBRARIES}) | ||||
| target_compile_definitions(${MODULE_NAME} PUBLIC -DNODEJS_API) | ||||
| if (WIN32) | ||||
|     target_compile_definitions(${MODULE_NAME} PUBLIC /O2) | ||||
| endif() | ||||
| 
 | ||||
| add_executable(Audio-Test ${SOURCE_FILES} test/audio/main.cpp) | ||||
| target_link_libraries(Audio-Test ${REQUIRED_LIBRARIES}) | ||||
|  | ||||
| @ -299,7 +299,7 @@ void AudioInput::consume(const void *input, size_t frameCount, size_t channels) | ||||
| 	    frameCount = (size_t) result; | ||||
| 	    input = this->resample_buffer; | ||||
| 
 | ||||
| 	    audio::apply_gain(input, this->_channel_count, frameCount); | ||||
| 	    audio::apply_gain(this->resample_buffer, this->_channel_count, frameCount, this->_volume); | ||||
| 	} else if(this->_volume != 1) { | ||||
|         const auto byte_size = frameCount * this->_channel_count * sizeof(float); | ||||
|         if(this->resample_buffer_size < byte_size) { | ||||
| @ -311,8 +311,7 @@ void AudioInput::consume(const void *input, size_t frameCount, size_t channels) | ||||
|         memcpy(this->resample_buffer, input, byte_size); | ||||
|         input = this->resample_buffer; | ||||
| 
 | ||||
| 
 | ||||
|         audio::apply_gain(input, this->_channel_count, frameCount); | ||||
|         audio::apply_gain(this->resample_buffer, this->_channel_count, frameCount, this->_volume); | ||||
| 	} | ||||
| 
 | ||||
| 	auto begin = chrono::system_clock::now(); | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
|     "start-n": "electron . -t --disable-hardware-acceleration --no-single-instance -u=https://clientapi.teaspeak.de/ -d", | ||||
|     "start-nd": "electron . -t --disable-hardware-acceleration --no-single-instance -u=http://clientapi.teaspeak.dev/ -d", | ||||
|     "start-01": "electron . --updater-channel=test -u=http://dev.clientapi.teaspeak.de/ -d --updater-ui-loader_type=0 --updater-local-version=1.0.1", | ||||
|     "start-devel-download": "electron . --disable-hardware-acceleration --gdb --debug --updater-ui-loader_type=2 --updater-ui-ignore-version -t -u http://localhost:8081/", | ||||
|     "start-s": "electron . --disable-hardware-acceleration --gdb --debug --updater-ui-loader_type=3 --updater-ui-ignore-version -t -u http://localhost:8081/", | ||||
|     "dtest": "electron . dtest", | ||||
|     "compile-sass": "sass --update .:.", | ||||
|  | ||||
| @ -10,7 +10,8 @@ | ||||
|     "baseUrl": ".", | ||||
|     "paths": { | ||||
|       "tc-shared/*": ["imports/shared-app/*"], | ||||
|       "tc-loader": ["imports/loader"] | ||||
|       "tc-loader": ["imports/loader"], | ||||
|       "svg-sprites/*": ["imports/svg-sprites/*"] | ||||
|     } | ||||
|   }, | ||||
|   "exclude": [ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user