{% extends "base.html" %}{% load i18n static %}
{% load djacore_tags %}{% load comments_tags %}{% load default_tags %}{% load mptt_tags %}{% load static %}
{% load cache %}
{% block meta %}
    {% with meta=obj.get_meta_tags %}
        <title>{% if meta.title %}{{ meta.title }}{% else %}{{ obj.title }}{% endif %}-{{ obj.category.name }}-{{ site_name }}</title>
        <meta name="description" content="{{ meta.description|slice:summary_length }}">
        <meta name="keywords" content="{{ meta.keywords }}">
        
        <!-- Open Graph -->
        <meta property="og:type" content="{{ meta.og.type }}">
        <meta property="og:title" content="{{ meta.og.title }}">
        <meta property="og:description" content="{{ meta.og.description }}">
        <meta property="og:url" content="{{site_url}}{{ meta.og.url }}">
        
        <!-- Twitter Card -->
        <meta name="twitter:card" content="{{ meta.twitter.card }}">
        <meta name="twitter:title" content="{{ meta.twitter.title }}">
        <meta name="twitter:description" content="{{ meta.twitter.description }}">
    {% endwith %}
{% endblock %}

{% block header %}
{% include "includes/header.html" %}
{% endblock %}
{% block breadcrumb %}
<nav aria-label="breadcrumb">
  <ol class="breadcrumb">
    <li class="breadcrumb-item"><a href="{% get_home_url %}">首页</a></li>
    {% ancestorsnode obj.category True as breadcrumb %}
    {% for item in breadcrumb %}
    <li class="breadcrumb-item"><a href="{{ item.get_absolute_url }}">{{ item.name }}</a></li>
    {% endfor %}
    <li class="breadcrumb-item active" aria-current="page">内容详情</li>
  </ol>
</nav>
{% endblock %}
{% block body_main %}
<style>
  .hidden { display: none; }
.cursor-zoom-in { cursor: zoom-in; }
.cursor-zoom-out { cursor: zoom-out; }
.object-contain { object-fit: contain; }

</style>
<div class="row" style="min-height:80vh">
  <div class="col-md-8">
    <div >
      <img src="{% if img_small %}{{ uploadpath }}{{ img_small }}{% else %}{{ obj.image.url }}{% endif %}" 
         alt="{{ obj.alt_text }}"
         class="h-100 w-100 cursor-zoom-in"
         loading="lazy"
         data-zoomable
         onclick="toggleImageZoom(this)">
    </div>
    <!-- 遮罩层 -->
    <div id="zoomOverlay" class="bg-black cursor-zoom-out inset-0 z-50 hidden" onclick="toggleImageZoom()" style="
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 999;
">
  <img id="zoomedImage" class="h-100 object-contain p-4 w-100" loading="eager">
</div>
    <div class="accordion" id="accordionExample">
      {% for key,value in exif_data.items %}
      <div class="accordion-item">
        <h2 class="accordion-header">
          <button class="accordion-button{% if forloop.first %}{% else %} collapsed{% endif %} " type="button" data-bs-toggle="collapse" data-bs-target="#card-{{forloop.counter}}" aria-expanded="{% if forloop.first %}true{% else %}false{% endif %}" aria-controls="card-{{forloop.counter}}">
            {{key}}
          </button>
        </h2>
        <div id="card-{{forloop.counter}}" class="accordion-collapse collapse {% if forloop.first %}show{% endif %} " data-bs-parent="#accordionExample">
          <div class="accordion-body">
            <div class="row">
              {% for k,v in value.items %}
              <div class="col-md-6">
                <div class="d-flex justify-content-between text-wrap">
                  <strong>{{k}}</strong>
                  <p class="text-break text-secondary">{% if k == 'gps纬度' or k == 'gps经度' %}******{% else %}{{v}}{% endif %}</p>
                  
                </div>
              </div>
              {% endfor %}
            </div>
          </div>
        </div>
      </div>
      
      {% endfor %}
    </div>

  </div>
  <div class="col-md-3">
    <div class="card card-secondary">
      <div class="card-body">
        <div class="dropdown">
          <button class="btn btn-success dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
            下载
          </button>
          <ul class="dropdown-menu">
          {% for i  in obj.ImageSizePreset %}<li><a class="dropdown-item downloadBtn" href="/image/{{obj.pk}}/{{i}}/">{{i.label}}<br></a></li>{% endfor %}
          </ul>
        </div>
        <hr>
        <div>心：53 下次次数：</div>
        <hr>
        <div class="d-flex">
          <div class="ratio ratio-1x1" style="width:4rem">{% if obj.editor.profile.avatar %}<img src="{{ obj.editor.profile.avatar }}" alt="" class="rounded-circle">{% else %} <i class="bi bi-person-circle text-secondary" style="font-size:3rem"></i>   {% endif %}</div>
          <div>{{obj.editor.username}}</div>
        </div>

        
        
      </div>
      
      
      
    </div>
  </div>
</div>
<script>
  function toggleImageZoom(imgElement) {
    const overlay = document.getElementById('zoomOverlay');
    const zoomedImg = document.getElementById('zoomedImage');
    
    if (!overlay.classList.contains('hidden')) {
        // 关闭大图
        overlay.classList.add('hidden');
    } else if (imgElement) {
        // 打开大图
        zoomedImg.src = imgElement.src;
        overlay.classList.remove('hidden');
    }
}

</script>
<!-- Bootstrap 5 等待模态框 -->
<div class="modal" id="waitModal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-body text-center py-4">
        <div class="spinner-border text-primary mb-3" role="status">
          <span class="visually-hidden">Loading...</span>
        </div>
        <h5>图片生成中，请稍候...</h5>
        <div class="progress mt-3">
          <div class="progress-bar progress-bar-striped progress-bar-animated" 
               style="width: 100%"></div>
        </div>
      </div>
      <div class="modal-footer justify-content-center">
        <!-- 新增取消按钮 -->
        <button type="button" class="btn btn-secondary" id="cancelBtn">
          <i class="bi bi-x-circle me-2"></i>取消
        </button>
      </div>
    </div>
  </div>
</div>

<script>
  // 全局中断控制器
  let abortController = null;
  
  document.querySelectorAll('.downloadBtn').forEach(btn => {
    btn.addEventListener('click', async function(e) {
      e.preventDefault();
      const target = e.currentTarget;
      const originalHref = target.href;
      
      try {
        // 初始化中断控制器
        abortController = new AbortController();
        
        const response = await fetch(originalHref, {
          signal: abortController.signal
        });
  
        if (response.status === 202) {
          const modal = new bootstrap.Modal('#waitModal');
          modal.show();
  
          // 绑定取消按钮事件
          document.getElementById('cancelBtn').onclick = () => {
            abortController.abort();
            modal.hide();
          };
  
          await pollWithTimeout(
            () => fetch(originalHref, { signal: abortController.signal }),
            300000,
            () => modal.hide()
          );
  
          // 成功后的处理
          target.removeEventListener('click', arguments.callee);
          target.click();
        } else {
          throw new Error(`未预期的响应状态: ${response.status}`);
        }
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('用户主动取消下载');
          return;
        }
        console.error('下载流程异常:', error);
        showErrorToast(error.message);
      }
    });
  });
  
  // 强化版轮询函数
  async function pollWithTimeout(fetcher, timeout, cleanup) {
    return new Promise((resolve, reject) => {
      const startTime = Date.now();
      const intervalId = setInterval(async () => {
        try {
          const res = await fetcher();
          
          if (res.status === 200) {
            clearInterval(intervalId);
            cleanup?.();
            resolve();
          } else if (Date.now() - startTime > timeout) {
            throw new Error('服务器响应超时');
          }
        } catch (err) {
          clearInterval(intervalId);
          cleanup?.();
          reject(err);
        }
      }, 2000);
  
      // 监听中止信号
      abortController.signal.addEventListener('abort', () => {
        clearInterval(intervalId);
        reject(new DOMException('操作已取消', 'AbortError'));
      });
    });
  }
  </script>
  
{% endblock %}


